用promise生成数据集

我目前正在尝试生成一个javascript对asynchronous调用数组,但我似乎无法得到正确的顺序。

generateDataPoints: function (iterable, source, arg) { let pairs = [] let prevTime = 0 for (let index in iterable) { let event = iterable[index] getTime(event.valueOf()).then(function (time) { query(source[arg], event.valueOf()).then(function(val) { if (time !== prevTime) { prevTime = time pairs.push([time, val]) console.log(pairs) // This works as expected but only happens after the program returns } else { Promise.resolve() } }) }) } return Promise.resolve(pairs) } 

问题是我返回后发生“pairs.push ..”命令。 我无法弄清究竟是怎么回事,我怎样才能同步这个过程。 任何帮助表示赞赏。

您正在混合同步代码(如for循环)与asynchronous代码。 尝试这样的事情:

 function generateDataPoints(iterable, source, arg) { let prevTime = 0 [...iterable].reduce((promiseChain, event) => { let pairs; return promiseChain .then(p => { pairs = p; return Promise.all([ getTime(event.valueOf()), query(source[arg], event.valueOf()) ]) }) .then(([time, val]) => { if (time !== prevTime) { prevTime = time return pairs.concat([[time, val]]); } else { return pairs; } }); }) }, Promise.resolve([])); } 

这减less了iterable成顺序的Promise链,最终将包含所有的对。

如果你的环境允许,你也可以把你的函数转换成一个asynchronous函数:

 generateDataPoints: async function (iterable, source, arg) { let pairs = [] let prevTime = 0 for (let index in iterable) { let event = iterable[index] const [time, val] = await Promise.all([ getTime(event.valueOf()), query(source[arg], event.valueOf()) ]); if (time !== prevTime) { prevTime = time pairs.push([time, val]) } } return pairs; } 

编辑

仔细一看,看起来你不需要序列化这些Promise。 您可能可以并行运行它们:

 function generateDataPoints(iterable, source, arg) { Promise.all( [...iterable].map(event => Promise.all([ getTime(event.valueOf()), query(source[arg], event.valueOf()) ]) ).then(pairs => { let prevTime = 0 return pairs.filter(([time, val]) => { if (time !== prevTime) { prevTime = time; return true; } else { return false; } }); }); }