setTimeout on异步函数



我有一个异步函数,我想在触发之前有5000ms的延迟。我正试图使用setTimeout()来实现这一点。这个异步函数在循环中运行多次,每次传递不同的数据,因此这里不能使用setInterval()

问题:异步函数立即触发,没有延迟(控制台打印5 Done消息立即'和循环,没有任何延迟。发生了什么,我该怎么解决?

Javascript代码

someFunction(listings, function() {
    for (var i in listings ) {
        var listing = listings[i];
        setTimeout(asyncFunction(listing, function(data) {
            console.log('Done');
        }), 5000);
    }
});

必须将该函数封装在另一个函数中。目前,您正在调用该函数,并将返回值作为参数传递给setTimeout。下面的代码将(正确地)将一个函数传递给setTimeout。5秒后,函数执行。

由于作用域问题,我不得不添加两个函数来实现所需的行为。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);

最新更新