如何在JavaScript中parsing后立即处理asynchronous结果?

我有一个asynchronous函数需要相当多的时间来callback,需要运行一个input数组,并将结果传递给后续操作。 我最初的方法是基于Promise的:

Promise.all(entries.map((entry) => { return new Promise((resolve, reject) => { processEntry(entry, resolve); }); })).then((outputs) => { outputs.forEach((output) => { return console.log(output); }); callback(); }); 

与此有关的问题是,输出只在得到解决之后得到处理(或在这种情况下logging)。 为了让他们尽快解决问题,我尝试了这种更老式的方法:

 var i = 0; entries.forEach((entry) => { processEntry(entry, (output) => { console.log(output); if (++i >= entries.length) callback(); }); }); 

这适用于我特殊的情况,但似乎不是一个正确的通用解决scheme,因为不再保证输出顺序。

为了达到预期的效果,至今我可以想到的最好的方法是在entries填入输出为原始索引的数组,并且每当新的输出出现时,就用数组的起始处理输出单独的滑动索引,当它达到一个undefined时候停止。

有没有更好的方法来实现这一目标?

读完这些注释之后,您想要启动所有processEntry但是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); 

如果你不熟悉async/await ,你仍然可以使用promise

那么你可以用这种方式尝试

 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) })