顺序执行承诺图 [英] Execute promises map sequentially

查看:42
本文介绍了顺序执行承诺图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我编写了一个在循环(映射)中调用的函数,并且该函数正在使用promises.现在,我希望该函数同步运行并在调用下一个实例之前退出.

I have written a function that is being called in a loop (map) and that function is using promises. Now, I want that function to run synchronously and exit before its next instance is called.

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被调用了五次,但是我希望每个实例仅在实例返回值之前被调用.目前,它的行为并非如此,而是并行调用了五次.

t2 is beingcalled five times, but I want each instance to be called only after the instance before it has returned the value. Currently its not behaving like that but invoking the function five times in parallel.

由于项目限制,我无法使用async/await.

I can't use async/await due to project limitations.

推荐答案

您当前代码的问题是,像 forEach 这样的 Promise.prototype.map 不会等待内部调用的异步功能完成.(除非您告诉解释器使用 await .then 明确地这样做,否则不会等待异步调用.)

The problem with your current code is that Promise.prototype.map, like forEach, does not wait for asynchronous functions called inside it to complete. (No asynchronous call will ever be waited for unless you tell the interpreter to do so explicitly with await or .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 :

Or if you want to use reduce instead of 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的半永久变量:

Or, if you need the sequential functionality to be encapsulated in t2, then have t2 have a semi-persistent variable of the previous Promise it generated:

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));

这篇关于顺序执行承诺图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆