javascript 异步延迟JS直到满足条件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7559386/
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
Asynchronously delay JS until a condition is met
提问by Amy B
I have a class, ChatRoom
, that can only render after it receives a long-running HTTP request (it could take 1 second or 30 seconds). So I need to delay rendering until ChatRoom.json
is not null.
我有一个类,ChatRoom
,它只能在收到长时间运行的 HTTP 请求后才能呈现(可能需要 1 秒或 30 秒)。所以我需要延迟渲染直到ChatRoom.json
不为空。
In the code below, I'm using Closure Library's goog.async.ConditionalDelay
. It works, but is there a better way (maybe without needing Closure Library) to do this?
在下面的代码中,我使用了 Closure 库的goog.async.ConditionalDelay
. 它有效,但是有没有更好的方法(也许不需要 Closure Library)来做到这一点?
ChatRoom.prototype.json = null; // received after a long-running HTTP request.
ChatRoom.prototype.render = function() {
var thisChatRoom = this;
function onReady() {
console.log("Received JSON", thisChatRoom.json);
// Do rendering...
}
function onFailure() {
alert('Sorry, an error occurred. The chat room couldn\'t open');
}
function isReady() {
if (thisChatRoom.json != null) {
return true;
}
console.log("Waiting for chat room JSON...");
return false;
}
// If there is a JSON request in progress, wait until it completes.
if (isReady()) {
onReady();
} else {
var delay = new goog.async.ConditionalDelay(isReady);
delay.onSuccess = onReady;
delay.onFailure = onFailure;
delay.start(500, 5000);
}
}
Note that "while (json == null) { }" isn't possible because that would be synchronous (blocking all other JS execution).
请注意,“while (json == null) { }” 是不可能的,因为这将是同步的(阻止所有其他 JS 执行)。
回答by ?ime Vidas
Consider this:
考虑一下:
(function wait() {
if ( chatroom.json ) {
chatroom.render();
} else {
setTimeout( wait, 500 );
}
})();
This will check every half second.
这将每半秒检查一次。
Live demo:http://jsfiddle.net/kBgTx/
现场演示:http : //jsfiddle.net/kBgTx/
回答by Lewis James-Odwin
You could also achieve this using lodash's debouncer with recursion.
你也可以使用 lodash 的 debouncer with recursion 来实现这一点。
import _debounce from 'lodash/debounce';
const wait = (() => {
if ( chatroom.json ) {
chatroom.render();
} else {
_debounce(wait, 500)();
}
})();
回答by pangolin
The answer I came up with is like this:
我想出的答案是这样的:
var count = 0;
// Number of functions that need to run. This can be dynamically generated
// In this case I call check(data, cb) a total of 3 times
var functionNum = 3;
function toCallAfter(){
console.log('I am a delayed function');
}
I had this for a check function that ran once regularly and twice in a loop:
我有一个检查函数,它定期运行一次,循环运行两次:
check(data, function(err){ // check is my asynchronous function to check data integrity
if (err){
return cb(null, { // cb() is the return function for the containing function
errCode: 'MISSINGINFO',
statusCode: 403,
message : 'All mandatory fields must be filled in'
});
} // This part here is an implicit else
count++; // Increment count each time required functions complete to
// keep track of how many function have completed
if (count === functionNum) {
return anon();
}
return;
});
// Run twice more in a loop
for(var i = 0; i < 2; i++) {
check(data, function(err) { // calls check again in a loop
if (err){
return cb(null, {
errCode: 'MISSINGINFO',
statusCode: 403,
message : 'All mandatory fields must be filled in'
});
}
count++;
if (count === functionNum) {
return toCallAfter();
}
return;
});
}
Lastly, I'd like to point out a significant performance fault in the alternate (and extraordinarily common) answer:
最后,我想指出备用(并且非常常见)答案中的一个重大性能错误:
(function wait() {
if ( chatroom.json ) {
chatroom.render();
} else {
setTimeout( wait, 500 );
}
})();
In this case, you are essentially holding the browser or server (If using node.js) hostage for 500 milliseconds for every check which is an incredibly long time for a computer. Meaning a huge performance hit. My solution of directly keeping track of the required completed functions is free from time restraints and will run instantly as soon as all functions complete.
在这种情况下,您实际上是在每次检查时将浏览器或服务器(如果使用 node.js)作为人质 500 毫秒,这对计算机来说是非常长的时间。意味着巨大的性能冲击。我的直接跟踪所需完成功能的解决方案不受时间限制,并且会在所有功能完成后立即运行。