Wait until all promises complete even if some rejected

前端 未结 18 1990
醉酒成梦
醉酒成梦 2020-11-21 04:55

Let\'s say I have a set of Promises that are making network requests, of which one will fail:

// http://does-not-exist will throw a TypeError
va         


        
18条回答
  •  我寻月下人不归
    2020-11-21 05:44

    I know that this question has a lot of answers, and I'm sure must (if not all) are correct. However it was very hard for me to understand the logic/flow of these answers.

    So I looked at the Original Implementation on Promise.all(), and I tried to imitate that logic - with the exception of not stopping the execution if one Promise failed.

      public promiseExecuteAll(promisesList: Promise[] = []): Promise<{ data: any, isSuccess: boolean }[]>
      {
        let promise: Promise<{ data: any, isSuccess: boolean }[]>;
    
        if (promisesList.length)
        {
          const result: { data: any, isSuccess: boolean }[] = [];
          let count: number = 0;
    
          promise = new Promise<{ data: any, isSuccess: boolean }[]>((resolve, reject) =>
          {
            promisesList.forEach((currentPromise: Promise, index: number) =>
            {
              currentPromise.then(
                (data) => // Success
                {
                  result[index] = { data, isSuccess: true };
                  if (promisesList.length <= ++count) { resolve(result); }
                },
                (data) => // Error
                {
                  result[index] = { data, isSuccess: false };
                  if (promisesList.length <= ++count) { resolve(result); }
                });
            });
          });
        }
        else
        {
          promise = Promise.resolve([]);
        }
    
        return promise;
      }
    

    Explanation:
    - Loop over the input promisesList and execute each Promise.
    - No matter if the Promise resolved or rejected: save the Promise's result in a result array according to the index. Save also the resolve/reject status (isSuccess).
    - Once all Promises completed, return one Promise with the result of all others.

    Example of use:

    const p1 = Promise.resolve("OK");
    const p2 = Promise.reject(new Error(":-("));
    const p3 = Promise.resolve(1000);
    
    promiseExecuteAll([p1, p2, p3]).then((data) => {
      data.forEach(value => console.log(`${ value.isSuccess ? 'Resolve' : 'Reject' } >> ${ value.data }`));
    });
    
    /* Output: 
    Resolve >> OK
    Reject >> :-(
    Resolve >> 1000
    */
    

提交回复
热议问题