如何处理异步函数和集合

How to deal with async functions and collections?

本文关键字:异步 函数 集合 处理 何处理      更新时间:2023-09-26

假设我们有一个函数foo(item, callback)和一个集合items

我想做的是用执行foo返回的值替换items中的每个项,就像Array.map()一样。

但问题来了:foo的结果是在回调中产生的,所以我在回调之外无法访问它(显然我无法更改foo来满足我的需求)。

你可以试试这样的方法

var results = [];
items.map((function(el) {
    foo(el, function(result) {results.push(time)});
});

但是,您不知道results系列何时"准备就绪"。

我完全没有头绪我该怎么办?模式是什么

EDIT:我更感兴趣的是Vanilla Javascript实现这一点的方法,而不是工具/库,它们无论如何都是可以接受的答案

在香草JS中,我会这样做:

var items = ['item 1', 'item 2', 'item 3']
function foo(item, callback) {
    // this is provided just to test the async nature of your callback
    setTimeout(function () {
        callback.call(null, item + ' async')
    }, Math.random() * 5000);
}

var results = [];
var count = 0;
items.forEach(function (element, index, array) {
    foo(element, function (result) {
        results[index] = result;
        // the actual "ready" check
        if (++count == items.length) {
            // here you should notify your code that all items have been replaced
            // after a random number of seconds between 1 and 5 in the current example, it should
            // write ['item 1 async', 'item 2 async', 'item 3 async']
            console.log(results);
        }
    })
});

我不知道这是一种模式还是最好的方法,但我认为它简单快捷。请注意,forEach仅适用于IE9+。对于IE<9可以使用jQuery.each,也可以手动编写for循环(但要小心闭包和索引)。

当使用异步库时,这变得非常琐碎。

async.each(items, function(el, callback) {
    foo(el, function(result) {
        callback(result);
    });
}, function(results) {
    doSomethingWith(results); //results being an array of the callbacked results.
});