这是我在 stackoverflow 上的第一篇文章,所以如果我遇到一个彻头彻尾的傻瓜,或者如果我无法让自己完全清楚,请不要对我发火。 :-)
这是我的问题:我正在尝试编写一个 javascript 函数,通过检查第一个函数的完成然后执行第二个函数来将两个函数“绑定(bind)”到另一个函数。
显然,解决这个问题的简单方法是编写一个元函数,在其范围内调用这两个函数。但是,如果第一个函数是异步的(特别是 AJAX 调用),而第二个函数需要第一个函数的结果数据,那根本行不通。
我对解决方案的想法是给第一个函数一个“标志”,即一旦调用它就创建一个公共(public)属性“this.trigger”(初始化为“0”,完成后设置为“1”);这样做应该可以让另一个函数检查标志的值([0,1])。如果满足条件(“trigger == 1”),则应调用第二个函数。
以下是我用于测试的抽象示例代码:
<script type="text/javascript" >
/**/function cllFnc(tgt) { //!! first function
this.trigger = 0 ;
var trigger = this.trigger ;
var _tgt = document.getElementById(tgt) ; //!! changes the color of the target div to signalize the function's execution
_tgt.style.background = '#66f' ;
alert('Calling! ...') ;
setTimeout(function() { //!! in place of an AJAX call, duration 5000ms
trigger = 1 ;
},5000) ;
}
/**/function rcvFnc(tgt) { //!! second function that should get called upon the first function's completion
var _tgt = document.getElementById(tgt) ; //!! changes color of the target div to signalize the function's execution
_tgt.style.background = '#f63' ;
alert('... Someone picked up!') ;
}
/**/function callCheck(obj) {
//alert(obj.trigger ) ; //!! correctly returns initial "0"
if(obj.trigger == 1) { //!! here's the problem: trigger never receives change from function on success and thus function two never fires
alert('trigger is one') ;
return true ;
} else if(obj.trigger == 0) {
return false ;
}
}
/**/function tieExc(fncA,fncB,prms) {
if(fncA == 'cllFnc') {
var objA = new cllFnc(prms) ;
alert(typeof objA + '\n' + objA.trigger) ; //!! returns expected values "object" and "0"
}
//room for more case definitions
var myItv = window.setInterval(function() {
document.getElementById(prms).innerHTML = new Date() ; //!! displays date in target div to signalize the interval increments
var myCallCheck = new callCheck(objA) ;
if( myCallCheck == true ) {
if(fncB == 'rcvFnc') {
var objB = new rcvFnc(prms) ;
}
//room for more case definitions
window.clearInterval(myItv) ;
} else if( myCallCheck == false ) {
return ;
}
},500) ;
}
</script>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/strict.dtd >
<html>
<head>
<script type="text/javascript" >
<!-- see above -->
</script>
<title>
Test page
</title>
</head>
<body>
<!-- !! testing area -->
<div id='target' style='float:left ; height:6em ; width:8em ; padding:0.1em 0 0 0; font-size:5em ; text-align:center ; font-weight:bold ; color:#eee ; background:#fff;border:0.1em solid #555 ; -webkit-border-radius:0.5em ;' >
Test Div
</div>
<div style="float:left;" >
<input type="button" value="tie calls" onmousedown="tieExc('cllFnc','rcvFnc','target') ;" />
</div>
<body>
</html>
最佳答案
您可以利用 JS 的一个称为闭包的功能。将它与一种非常常见的 JS 模式相结合,称为“持续传递样式”,您就有了解决方案。 (这些东西都不是 JS 的原创,但在 JS 中被大量使用)。
// a function
function foo(some_input_for_foo, callback)
{
// do some stuff to get results
callback(results); // call our callback when finished
}
// same again
function bar(some_input_for_bar, callback)
{
// do some stuff to get results
callback(results); // call our callback when finished
}
foo(input1, function(results1) {
bar(results1, function(results2) {
alert(results2);
});
});
I have a long-running asynchronous operation, so I need to know when it finishes in order to start the next operation. So I need to make that state visible as a property. Then elsewhere I can run in a loop, repeatedly examining that property to see when it changes to the "completed" state, so I know when to continue.
setInterval 开始运行并使用 clearInterval 退出,以允许其他 JS 代码运行 - 但它基本上是一个“轮询循环”)。function cllFnc(tgt) { //!! first function
this.trigger = 0 ;
var trigger = this.trigger ;
var _tgt = document.getElementById(tgt) ; //!! changes the color...
_tgt.style.background = '#66f' ;
alert('Calling! ...') ;
setTimeout(function() { //!! in place of an AJAX call, duration 5000ms
trigger = 1 ;
},5000) ;
}
trigger 的当前值属性到一个名为 trigger 的新局部变量中.然后最后将 1 分配给该局部变量。没有其他人能够看到这一点。局部变量是函数私有(private)的。但无论如何你都不需要这样做,所以请继续阅读......]function cllFnc(tgt, finishedFunction) { //!! first function
var _tgt = document.getElementById(tgt) ; //!! changes the color...
_tgt.style.background = '#66f' ;
alert('Calling! ...') ;
setTimeout(function() { //!! in place of an AJAX call, duration 5000ms
finishedFunction(); // <-------- call function instead of set property
},5000) ;
}
tieExc helper 。只需很少的代码,您就可以轻松地将两个函数绑定(bind)在一起。var mySpan = "#myspan";
cllFnc(mySpan, function() { rcvFnc(mySpan); });
function getCustomerBillAmount(name, callback) {
$.get("/ajax/getCustomerIdByName/" + name, function(id) {
$.get("/ajax/getCustomerBillAmountById/" + id), callback);
});
}
callback接受客户账单金额,AJAX get call 将接收到的值传递给我们传递它的函数,所以 callback已经兼容,因此可以直接充当第二个 AJAX 调用的回调。因此,这本身就是将两个异步调用按顺序捆绑在一起并将它们包装在(从外部)看起来是单个异步函数的示例。function displayBillAmount(amount) {
$("#billAmount").text(amount);
}
getCustomerBillAmount("Simpson, Homer J.", displayBillAmount);
getCustomerBillAmount("Simpson, Homer J.", function(amount) {
$("#billAmount").text(amount);
});
function pubsub() {
var subscribers = [];
return {
subscribe: function(s) {
subscribers.push(s);
},
publish: function(arg1, arg2, arg3, arg4) {
for (var n = 0; n < subscribers.length; n++) {
subscribers[n](arg1, arg2, arg3, arg4);
}
}
};
}
finished = pubsub();
// subscribe as many times as you want:
finished.subscribe(function(msg) {
alert(msg);
});
finished.subscribe(function(msg) {
window.title = msg;
});
finished.subscribe(function(msg) {
sendMail("admin@mysite.com", "finished", msg);
});
lookupTaxRecords("Homer J. Simpson", finished.publish);
关于javascript - "Phased"在javascript中执行函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2552792/
我正在尝试测试是否存在表单。我是Rails新手。我的new.html.erb_spec.rb文件的内容是:require'spec_helper'describe"messages/new.html.erb"doit"shouldrendertheform"dorender'/messages/new.html.erb'reponse.shouldhave_form_putting_to(@message)with_submit_buttonendendView本身,new.html.erb,有代码:当我运行rspec时,它失败了:1)messages/new.html.erbshou
我在从html页面生成PDF时遇到问题。我正在使用PDFkit。在安装它的过程中,我注意到我需要wkhtmltopdf。所以我也安装了它。我做了PDFkit的文档所说的一切......现在我在尝试加载PDF时遇到了这个错误。这里是错误:commandfailed:"/usr/local/bin/wkhtmltopdf""--margin-right""0.75in""--page-size""Letter""--margin-top""0.75in""--margin-bottom""0.75in""--encoding""UTF-8""--margin-left""0.75in""-
我在使用omniauth/openid时遇到了一些麻烦。在尝试进行身份验证时,我在日志中发现了这一点:OpenID::FetchingError:Errorfetchinghttps://www.google.com/accounts/o8/.well-known/host-meta?hd=profiles.google.com%2Fmy_username:undefinedmethod`io'fornil:NilClass重要的是undefinedmethodio'fornil:NilClass来自openid/fetchers.rb,在下面的代码片段中:moduleNetclass
为了将Cucumber用于命令行脚本,我按照提供的说明安装了arubagem。它在我的Gemfile中,我可以验证是否安装了正确的版本并且我已经包含了require'aruba/cucumber'在'features/env.rb'中为了确保它能正常工作,我写了以下场景:@announceScenario:Testingcucumber/arubaGivenablankslateThentheoutputfrom"ls-la"shouldcontain"drw"假设事情应该失败。它确实失败了,但失败的原因是错误的:@announceScenario:Testingcucumber/ar
我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re
我遵循了教程http://gettingstartedwithchef.com/,第1章。我的运行list是"run_list":["recipe[apt]","recipe[phpap]"]我的phpapRecipe默认Recipeinclude_recipe"apache2"include_recipe"build-essential"include_recipe"openssl"include_recipe"mysql::client"include_recipe"mysql::server"include_recipe"php"include_recipe"php::modul
我遵循MichaelHartl的“RubyonRails教程:学习Web开发”,并创建了检查用户名和电子邮件长度有效性的测试(名称最多50个字符,电子邮件最多255个字符)。test/helpers/application_helper_test.rb的内容是:require'test_helper'classApplicationHelperTest在运行bundleexecraketest时,所有测试都通过了,但我看到以下消息在最后被标记为错误:ERROR["test_full_title_helper",ApplicationHelperTest,1.820016791]test
我正在尝试用ruby中的gsub函数替换字符串中的某些单词,但有时效果很好,在某些情况下会出现此错误?这种格式有什么问题吗NoMethodError(undefinedmethod`gsub!'fornil:NilClass):模型.rbclassTest"replacethisID1",WAY=>"replacethisID2andID3",DELTA=>"replacethisID4"}end另一个模型.rbclassCheck 最佳答案 啊,我找到了!gsub!是一个非常奇怪的方法。首先,它替换了字符串,所以它实际上修改了
我正在尝试从Postgresql表(table1)中获取数据,该表由另一个相关表(property)的字段(table2)过滤。在纯SQL中,我会这样编写查询:SELECT*FROMtable1JOINtable2USING(table2_id)WHEREtable2.propertyLIKE'query%'这工作正常:scope:my_scope,->(query){includes(:table2).where("table2.property":query)}但我真正需要的是使用LIKE运算符进行过滤,而不是严格相等。然而,这是行不通的:scope:my_scope,->(que
我正在尝试编写一个将文件上传到AWS并公开该文件的Ruby脚本。我做了以下事情:s3=Aws::S3::Resource.new(credentials:Aws::Credentials.new(KEY,SECRET),region:'us-west-2')obj=s3.bucket('stg-db').object('key')obj.upload_file(filename)这似乎工作正常,除了该文件不是公开可用的,而且我无法获得它的公共(public)URL。但是当我登录到S3时,我可以正常查看我的文件。为了使其公开可用,我将最后一行更改为obj.upload_file(file