Waiting for more than one concurrent await operation

前端 未结 4 1173
误落风尘
误落风尘 2020-11-22 03:25

How can I change the following code so that both async operations are triggered and given an opportunity to run concurrently?

const value1 = await getValue1A         


        
4条回答
  •  故里飘歌
    2020-11-22 04:16

    Use .catch() and Promise.all()

    Make sure you handle rejections correctly and you can safely use Promises.all() without facing unhandled rejections. (Edit: clarification per discussion: not the Error unhandled rejection but simply rejections that are not being handled by the code. Promise.all() will throw the first promise rejection and will ignore the rest).

    In the example below an array of [[error, results], ...] is returned to allow ease of processing results and/or errors.

    let myTimeout = (ms, is_ok) =>
      new Promise((resolve, reject) => 
        setTimeout(_=> is_ok ? 
                       resolve(`ok in ${ms}`) :
                       reject(`error in ${ms}`),
                   ms));
    
    let handleRejection = promise => promise
      .then((...r) => [null, ...r])
      .catch(e => [e]); 
    
    (async _=> {
      let res = await Promise.all([
        myTimeout(100, true),
        myTimeout(200, false),
        myTimeout(300, true),
        myTimeout(400, false)
      ].map(handleRejection));
      console.log(res);
    })();

    You may throw from within a catch() to stop waiting for all (and discard the results of the rest), however - you may only do it once per try/catch blocks so a flag has_thorwn need to be maintained and checked to make sure no unhandled errors happens.

    let myTimeout = (ms, is_ok) =>
      new Promise((resolve, reject) =>
        setTimeout(_=> is_ok ?
                       resolve(`ok in ${ms}`) :
                       reject(`error in ${ms}`),
                   ms));
    
    let has_thrown = false;
    
    let handleRejection = promise => promise
      .then((...r) => [null, ...r])
      .catch(e => {
        if (has_thrown) {
          console.log('not throwing', e);
        } else {
          has_thrown = 1;
          throw e;
        }
      });
    
    (async _=> {
      try {
        let res = await Promise.all([
          myTimeout(100, true),
          myTimeout(200, false),
          myTimeout(300, true),
          myTimeout(400, false)
        ].map(handleRejection));
        console.log(res);
      } catch(e) {
        console.log(e);
      }
      console.log('we are done');
    })();

提交回复
热议问题