假设我们有一个函数foo(item, callback)
和一个集合items
。
我要做的是将items
中的每个项目替换为执行foo
所返回的值,就像Array.map()
一样。
但问题出现了:foo
的结果在回调中产生,所以我无法在回调本身之外访问它(显然我无法改变foo
来满足我的需要)。
您可以尝试像
这样的方法var results = [];
items.map((function(el) {
foo(el, function(result) {results.push(time)});
});
但是,您无法知道您的results
收藏何时会准备好"。
我完全无能为力。 我该怎么办?模式是什么?
编辑:我对Vanilla Javascript更感兴趣的方法是实现这个,而不是工具/库,无论如何都是可接受的答案。
答案 0 :(得分:2)
使用async库时,这变得非常简单。
async.each(items, function(el, callback) {
foo(el, function(result) {
callback(result);
});
}, function(results) {
doSomethingWith(results); //results being an array of the callbacked results.
});
答案 1 :(得分:2)
在香草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循环(但要注意闭包和索引)。