异步结果在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()中。然后它们将按正确的顺序排列,当然,如果第一个在第二个之前完成,我想在第二个仍在处理的时候记录。啊,现在我明白了-不要挂起愚蠢的注释-不过,这很接近:dw
callback()
应该做什么?
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)

})