javascript 异步函数上的 setTimeout
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8279035/
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
setTimeout on Asynchronous function
提问by Nyxynyx
I have a asynchronous function that I want to have a 5000ms delay before being fired. I am trying to use setTimeout()
to achieve this. This async function occurs in a loop that runs several times, with the async function being passed different data each time, thus setInterval()
cannot be used here.
我有一个异步函数,我希望在被触发之前有 5000 毫秒的延迟。我正在尝试使用它setTimeout()
来实现这一目标。这个 async 函数出现在一个循环中,多次运行,每次 async 函数传递不同的数据,因此setInterval()
不能在这里使用。
Problem:The async function gets triggered instantly without delay (console prints 5 Done
messages instantly` and loops without any delay. What happened, and how can I solve it?
问题:异步函数立即触发,没有延迟(控制台Done
立即打印 5 条消息`并且没有任何延迟地循环。发生了什么,我该如何解决?
Javascript Code
Javascript代码
someFunction(listings, function() {
for (var i in listings ) {
var listing = listings[i];
setTimeout(asyncFunction(listing, function(data) {
console.log('Done');
}), 5000);
}
});
回答by Rob W
You have to wrap the function in another function. Currently, you're invoking the function, and passing the return value as an argument to setTimeout
. The code below will (correctly) pass a function to setTimeout
. After 5 seconds, the function executes.
您必须将该函数包装在另一个函数中。目前,您正在调用该函数,并将返回值作为参数传递给setTimeout
. 下面的代码将(正确地)将函数传递给setTimeout
. 5 秒后,函数执行。
I had to add twofunctions to achieve the desired behaviour, because of scoping issues. After 5 seconds, the loop has already finished, and the listing
variable would be equal to the last element in listings
.
由于范围问题,我不得不添加两个函数来实现所需的行为。5 秒后,循环已经完成,listing
变量将等于 中的最后一个元素listings
。
someFunction(listings, function() {
var counter = 0; // Define counter for 5 second-delays between each call
for (var i in listings ) {
var listing = listings[i];
(function(listing){ //Closure function
setTimeout(function(){ //setTimeout function
// Because of the closure, `listing` is unique
asyncFunction(listing, function(a, b) {
console.log('Done');
});
}, 5000 * ++counter); //Increase counter for each loop
})(listing);
}
});
回答by Thomas
If you are using ECMAScript6you can use Promise.
如果您使用ECMAScript6,则可以使用Promise。
So create a delay function that wrap the call to the setTimeout into a Promise:
因此,创建一个延迟函数,将 setTimeout 的调用包装到一个 Promise 中:
function delay(ms) {
return new Promise(function (resolve) { return setTimeout(resolve, ms); });
};
And you can use it like that :
你可以这样使用它:
someFunction(listings, function() {
for (var i in listings ) {
var listing = listings[i];
delay(5000).then(() => {
return asyncFunction(listing);
}).then(() => {
console.log('Done');
});
}
});
If you are using ECMAScript 2017you can use aync/await.
如果您使用的是ECMAScript 2017,则可以使用aync/await。
Async functions return promise so you don't have to change the code of the delay function.
异步函数返回承诺,因此您不必更改延迟函数的代码。
async someFunction(listings, function() {
for (var i in listings ) {
var listing = listings[i];
await delay(5000);
await asyncFunction(listing);
console.log('Done');
}
});
回答by RightSaidFred
Not knowing what your asyncFunction
does, it would seem that it could simply return the function you passed it.
不知道你asyncFunction
做了什么,它似乎可以简单地返回你传递给它的函数。
someFunction(listings, function() {
for (var i = 0; i < listings.length; ++i ) {
setTimeout(asyncFunction(listings[i], function(data) {
console.log('Done');
}), 5000 * i);
}
});
function asyncFunction( lstng, func ) {
return func;
}
Though I'd expect that you need to wrap up some additional logic.
虽然我希望你需要总结一些额外的逻辑。
function asyncFunction( lstng, func ) {
return function() {
// do some stuff with the listing
// then invoke the func
func();
}
}
Now your asyncFunction
wraps whatever is needed in a new function that is returned to the setTimeout
. The new function also invokes the callback you passed.
现在,您asyncFunction
将所需的任何内容包装在返回到setTimeout
. 新函数还会调用您传递的回调。
回答by island205
it's the difference.the key point is what is asyncFunction
do? can you paste it out?
这是区别。关键是asyncFunction
做什么?你能贴出来吗?
var foo=function(){
alert("BAR");
return function(){
alert("I AM!");
};
}
setTimeout(foo(),4000);
setTimeout(foo,5000);