我有一个异步函数,我想在触发之前有5000ms的延迟。我正试图使用setTimeout()
来实现这一点。这个异步函数在循环中运行多次,每次传递不同的数据,因此这里不能使用setInterval()
。
问题:异步函数立即触发,没有延迟(控制台打印5 Done
消息立即'和循环,没有任何延迟。发生了什么,我该怎么解决?
someFunction(listings, function() {
for (var i in listings ) {
var listing = listings[i];
setTimeout(asyncFunction(listing, function(data) {
console.log('Done');
}), 5000);
}
});
必须将该函数封装在另一个函数中。目前,您正在调用该函数,并将返回值作为参数传递给setTimeout
。下面的代码将(正确地)将一个函数传递给setTimeout
。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);
}
});
如果你正在使用ECMAScript6,你可以使用Promise
所以创建一个延迟函数,将对setTimeout的调用包装成一个Promise:
function delay(ms) {
return new Promise(function (resolve) { return setTimeout(resolve, ms); });
};
你可以这样使用:
someFunction(listings, function() {
for (var i in listings ) {
var listing = listings[i];
delay(5000).then(() => {
return asyncFunction(listing);
}).then(() => {
console.log('Done');
});
}
});
如果你使用的是ECMAScript 2017,你可以使用aync/await。
Async函数返回promise,因此您不必更改延迟函数的代码。
async someFunction(listings, function() {
for (var i in listings ) {
var listing = listings[i];
await delay(5000);
await asyncFunction(listing);
console.log('Done');
}
});
不知道您的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;
}
虽然我希望你需要包装一些额外的逻辑。
function asyncFunction( lstng, func ) {
return function() {
// do some stuff with the listing
// then invoke the func
func();
}
}
现在,您的asyncFunction
将所需的任何内容包装在返回给setTimeout
的新函数中。新函数还调用您传递的回调。
JSFIDDLE DEMO
这就是区别。关键是asyncFunction
是做什么的?你能把它粘贴出来吗?
var foo=function(){
alert("BAR");
return function(){
alert("I AM!");
};
}
setTimeout(foo(),4000);
setTimeout(foo,5000);