为了账号安全,请及时绑定邮箱和手机立即绑定

按顺序执行承诺映射

按顺序执行承诺映射

隔江千里 2021-09-30 09:49:54
我编写了一个在循环(映射)中调用的函数,并且该函数使用了 Promise。现在,我希望该函数同步运行并在调用其下一个实例之前退出。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。
查看完整描述

3 回答

?
手掌心

TA贡献1942条经验 获得超3个赞

您当前代码的问题在于Promise.prototype.map,像 一样forEach,不会等待在其中调用的异步函数完成。(除非您用await或明确告诉解释器这样做,否则不会等待异步调用.then)


有t1AWAIT的每个呼叫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));


查看完整回答
反对 回复 2021-09-30
?
九州编程

TA贡献1785条经验 获得超4个赞

(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 */)


查看完整回答
反对 回复 2021-09-30
?
四季花海

TA贡献1811条经验 获得超5个赞

以下是.reduce()与 async/await 结合使用时按顺序运行 Promise 的样子:


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

  }, [])


  console.log(arr1_mapped)


}


main()


查看完整回答
反对 回复 2021-09-30
  • 3 回答
  • 0 关注
  • 190 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信