如何在生成器中同时映射异步调用的结果?
var generator = (function *() {
var lotsOfThings = yield asyncTask.call(generator);
var mappedResults = yield lotsOfThings.map(thing => {
// fails with a syntax error unless you do a `for…of` loop, but also doesn’t run concurrently regardless
return (yield asyncTask.call(generator, thing));
});
// then do something with mappedResults
})();
generator.next();
function asyncTask(…query) {
somethingAsync(…query, (err, res) => this.next(res));
}
此外,即使在常规的 for...of
循环中,您也无法同时运行每个 asyncTask
。 yield
将导致每个任务之间暂停,本质上是发出同步 AJAX 请求。理想情况下,您希望它像使用 promises 一样工作,就像这个范例:
// these tasks will run concurrently (unlike the above example)
let promises = someThings.map(thing => {
return new Promise((resolve, reject) => {
somethingAsync((err, res) => {
resolve(res);
});
});
});
Promise.all(promises).then(/* do stuff */);
promise 方法可能会因为所有嵌套而变得毛茸茸,但好处是异步任务可以并发运行……而生成器看起来不错,但循环任务不是并发的。有什么想法吗?
最佳答案
我尝试在没有第三方库的情况下勾勒出类似的东西:
// Async runner
function async(generator){
var process = function(result){
if (result.done) {
return;
}
(Array.isArray(result.value) ? Promise.all(result.value) : result.value).then(function(value){
process(sequence.next(value));
});
};
var sequence = generator();
var next = sequence.next();
process(next);
};
// Generator function
var generator = function* () {
var list = yield getList();
console.log(list); // outputs [1, 2, 3, 4, 5]
var details = yield list.map(p => getDetails(p));
console.log(details); // outputs [11, 12, 13, 14, 15]
}
// Your async requests go here
function fakeAsync(f) {
return new Promise(function(resolve, reject) {
setTimeout(function() {
f(resolve);
}, 500);
});
}
function getList() {
return fakeAsync(function(resolve) {
resolve([1, 2, 3, 4, 5]);
});
}
function getDetails(i) {
return fakeAsync(function(resolve) {
resolve(i + 10);
});
}
async(generator);
这是您想要实现的目标吗?
关于javascript - 您如何同时映射生成器结果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32576115/