等待从 javascript 函数返回,直到满足条件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8336180/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Wait to return from a javascript function until condition met
提问by findchris
This is an odd problem. I have a client object that I am building up using Crockford-esque public/private members:
这是一个奇怪的问题。我有一个客户端对象,我正在使用 Crockford 式的公共/私有成员构建它:
var client = function() {
var that, remote_data, other_data;
// add public interface
that.doStuff = function(){...}
// wait for remote resources to load
remote_data = jsonRequest1();
other_data = jsonRequest2();
return that;
};
The problem I'm having is that I need to load some remote JSON resources prior to returning the new 'that' object (which signals a ready client). Data is returned asynchronously (obviously), and I am setting boolean variables to indicate when each remote resource has returned.
我遇到的问题是我需要在返回新的“那个”对象(它表示客户端准备就绪)之前加载一些远程 JSON 资源。数据是异步返回的(显然),我正在设置布尔变量以指示每个远程资源何时返回。
I've thought about doing something like the following:
我想过做如下事情:
return whenInitialized(function() { return that; });
The whenInitialized function returns whether or not both of the boolean flags are true. I'd use this with a combination of setInterval, but I am sure this won't work.
whenInitialized 函数返回两个布尔标志是否都为真。我会将它与 setInterval 结合使用,但我确信这行不通。
Would appreciate your suggestions.
将不胜感激您的建议。
回答by Jord?o
In order to run code afteran asynchronous operation has succeeded, you need a continuation. It can be just a callback that your code calls when the operations are complete.
为了在异步操作成功后运行代码,您需要一个continuation。它可以只是您的代码在操作完成时调用的回调。
Something like this:
像这样的东西:
var client = function(done) { // done is the callback
var that, remote_data, other_data;
// add public interface
that.doStuff = function(){...}
// wait for remote resources to load
var done1 = false, done2 = false;
var complete1 = function() { done1 = true; if (done2) done(); };
var complete2 = function() { done2 = true; if (done1) done(); };
remote_data = jsonRequest1(complete1);
other_data = jsonRequest2(complete2);
return that;
};
But these controlling flags are really annoying and don't really scale. A better, declarative way of doing this is using something like jQuery deferreds:
但是这些控制标志真的很烦人,而且不能真正扩展。一种更好的声明式方法是使用类似jQuery deferreds 的东西:
$.when(jsonRequest1(), jsonRequest2()).then(done);
回答by six8
You can do a loop (optionally with a timeout) to wait for the async to finish. Warning, this will (as requested) block all other functionality and may cause the browser to freeze if it takes much too long. However, you really should figure out an asynchronous way to do what you need instead of blocking like this.
您可以执行循环(可选地超时)以等待异步完成。警告,这将(根据要求)阻止所有其他功能,如果时间过长,可能会导致浏览器冻结。但是,您确实应该找出一种异步方式来执行您需要的操作,而不是像这样阻塞。
var syncRequest = function(options) {
var is_finished = false;
var result;
var finished_callback = function(response) {
is_finished = true;
result = response.result;
}
ajax_request(options, finished_callback);
// timeout in 30 seconds
var timeout = (new Date()).getTime() + 30000;
while ( !is_finished ) {
if ( (new Date()).getTime() >= timeout ) {
alert('Request timed out');
}
// do nothing, just block and wait for the request to finish
}
return result;
}