我编写了一个在循环(映射)中调用的函数,并且该函数正在使用promises。现在,我希望该函数同步运行并在调用下一个实例之前退出。
function t1(){
let arr1 = [1,2,3,4,5];
return Promise.map(arr1, (val) =>{
const params = {
"param1" : val1
};
return t2(params);
});
}
function t2(event){
return Promise.resolve()
.then({
//do something
//code doesn't reach here in sync manner. all five instance are invoked and then code reaches here for first instance and so on
})
.then({
//promise chaining. do something more
})
}
t2被调用了五次,但是我希望每个实例仅在实例返回值之前被调用。 目前,它的行为并非如此,而是并行调用了五次。
由于项目限制,我无法使用async / await。
答案 0 :(得分:4)
当前代码的问题在于,Promise.prototype.map
和forEach
一样,不等待内部调用的异步函数完成。 (除非您告诉解释器使用await
或.then
显式地执行此操作,否则不会等待异步调用。)
让t1
等待t2
的每个呼叫:
async function t1(){
let arr1 = [1,2,3,4,5];
const results = [];
for (const val of arr1) {
results.push(await t2(val));
}
return results;
}
或者如果您想使用reduce
而不是async
/ await
:
const delay = () => new Promise(res => setTimeout(res, 500));
function t1(){
let arr1 = [1,2,3,4,5];
return arr1.reduce((lastProm, val) => lastProm.then(
(resultArrSoFar) => t2(val)
.then(result => [...resultArrSoFar, result])
), Promise.resolve([]));
}
function t2(event){
return delay().then(() => {
console.log('iter');
return event;
});
}
t1()
.then(results => console.log('end t1', results));
或者,如果您需要将顺序功能封装在t2中,则让t2具有其之前生成的Promise的半永久变量:
const delay = () => new Promise(res => setTimeout(res, 500));
const t1 = () => {
return Promise.all([1, 2, 3, 4].map(t2));
};
const t2 = (() => {
let lastProm = Promise.resolve();
return (event) => {
const nextProm = lastProm
.catch(() => null) // you may or may not want to catch here
.then(() => {
// do something with event
console.log('processing event');
return delay().then(() => event);
});
lastProm = nextProm;
return nextProm;
};
})();
t1().then(results => console.log('t1 done', results));
答案 1 :(得分:1)
(function loop(index) {
const next = promiseArray[index];
if (!next) {
return;
}
next.then((response) => {
// do Something before next
loop(index + 1);
}).catch(e => {
console.error(e);
loop(index + 1);
});
})(0 /* startIndex */)
答案 2 :(得分:-2)
这是将.reduce()
与async / await结合使用时按顺序运行Promises的样子:
async function main() {
const t2 = (v) => Promise.resolve(v*2)
const arr1 = [1,2,3,4,5];
const arr1_mapped = await arr1.reduce(async (allAsync, val) => {
const all = await allAsync
all.push(await t2(val) /* <-- your async transformation */)
return all
}, Promise.resolve([]))
console.log(arr1_mapped)
}
main()