我目前正在尝试使用 javascript 中的异步调用生成一个对数组,但我似乎无法按正确的顺序获取它。
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 循环)与异步代码混合在一起。尝试这样的事情:
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([]));
}
这会将 iterable
简化为顺序 Promise 链,最终将包含所有对。
如果您的环境允许,您还可以将函数转换为异步函数,只需进行少量更改即可:
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;
}
});
});
}
关于javascript - 生成带有 promise 的数据集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46897890/