异步结果在JavaScript中解析后,我如何按顺序处理它们?
我有一个异步函数,需要花费相当多的时间来回调,它需要运行一个输入数组,并将结果传递给后续操作。我最初的方法是基于承诺的:异步结果在JavaScript中解析后,我如何按顺序处理它们?,javascript,node.js,asynchronous,ecmascript-6,promise,Javascript,Node.js,Asynchronous,Ecmascript 6,Promise,我有一个异步函数,需要花费相当多的时间来回调,它需要运行一个输入数组,并将结果传递给后续操作。我最初的方法是基于承诺的: Promise.all(entries.map((entry) => { return new Promise((resolve, reject) => { processEntry(entry, resolve); }); })).then((outputs) => { outputs.forEach((output) => {
Promise.all(entries.map((entry) => {
return new Promise((resolve, reject) => {
processEntry(entry, resolve);
});
})).then((outputs) => {
outputs.forEach((output) => {
return console.log(output);
});
callback();
});
这样做的问题是,只有在所有输出都已解决后,才会对其进行处理(或在本例中记录)。为了让他们在解决问题后立即登录,我尝试了这种更老式的方法:
var i = 0;
entries.forEach((entry) => {
processEntry(entry, (output) => {
console.log(output);
if (++i >= entries.length)
callback();
});
});
这适用于我非常特殊的情况,但似乎不是一个正确的通用解决方案,因为不再有任何保证输出将是有序的
到目前为止,我能想到的实现所需效果的最佳方法是在条目
中的原始索引处用输出填充数组,并且每次出现新的输出时,您都使用一个单独的滑动索引从数组的开始处处理输出,该滑动索引在到达未定义的
时停止
有没有更优雅的方法来实现这一点?阅读注释后,您希望启动所有的
processEntry
,但要按顺序处理它们
entries.map(entry => new Promise((resolve, reject) => {
processEntry(entry, resolve);
}))
.reduce((promise, entry) => {
return promise.then(() => entry)
.then(value => console.log(value));
}, Promise.resolve())
.then(() => {
// all done at this point
});
如果你想要一个决赛,那么所有的结果
entries.map(entry => new Promise((resolve, reject) => {
processEntry(entry, resolve);
}))
.reduce((promise, entry) => {
return promise.then(results => entry.then(value => {
// process results in order but as soon as possible
console.log(value)
// concat to the results
return results.concat(value);
}));
}, Promise.resolve([]))
.then(results => {
// all results in correct order
});
我看到您现在正在使用
es6
,也许您可以尝试使用async/await
,您可以看到
因此,您的代码可能如下所示:
const processEntry = async (entry) => {
// ...other code
}
const getFinalResult = async (entries) => {
const result = [];
for (let i = 0; i < entries.length; i++) {
const data = await processEntry(entries[i]);
result.push(data);
}
return result
}
const result = await getFinalResult(entries);
此方法的问题是,
processEntry
将依次发生。我希望它们并行进行,并按顺序记录结果。如果是这样,您可以尝试使用Promise.all
,然后按索引对日志进行排序。可能我的问题不够清楚,我正在尝试避免Promise.all
,因为我想在它们仍在处理时进行日志记录,不要等到一切都处理好了才开始记录日志。这不是和我的第二个例子一样有问题吗?他们可能不会按原始顺序登录。如何在不等待所有异步任务完成的情况下获得正确的顺序?在Promise.all()中。然后它们将按正确的顺序排列,当然,如果第一个在第二个之前完成,我想在第二个仍在处理的时候记录。啊,现在我明白了-不要挂起愚蠢的注释-不过,这很接近:dwcallback()
应该做什么?
let promise = Promise.resolve();
let result = [];
for (let i = 0; i < entries.length; i++) {
((entry) => {
promise = promise.then(() => {
const data = processEntry(entry);
result.push(result);
})
}
)(entries[i)
}
promise.then(() => {
callback(result)
})