How do you implement a “raceToSuccess” helper, given a list of promises?

后端 未结 7 1788
孤城傲影
孤城傲影 2020-12-02 23:37

I\'m puzzled by something in the ES6 Promise API. I can see a clear use case for submitting multiple async jobs concurrently, and \"resolving\" on the first success. This wo

7条回答
  •  自闭症患者
    2020-12-02 23:51

    Old topic but here's my entry; it's essentially @loganfsmyth's solution, but with a few more checks to conform to conventions established by Promise.all():

    • Empty array as input returns (synchronously) an already resolved promise
    • Non-promise entries in the array results in the 1st such entry to be used as the resolved value

    Promise.any = a => {
      return !a.length ?
        Promise.resolve() :
        Promise.all(a.map(
          e => (typeof e.then !== 'function') ?
            Promise.reject(e) :
            e.then(
              result => Promise.reject(result),
              failure => Promise.resolve(failure)
            )
        )).then(
          allRejected => Promise.reject(allRejected),
          firstResolved => Promise.resolve(firstResolved)
        );
    };
    
    // Testing...
    
    function delayed(timeout, result, rejected) {
      return new Promise((resolve, reject) => {
        setTimeout(
          () => rejected ? reject(result) : resolve(result),
          timeout);
      });
    }
    
    Promise.any([
      delayed(800, 'a'),
      delayed(500, 'b'),
      delayed(250, 'c', true)
    ]).then(e => {
      console.log('First resolved (expecting b):', e);
    });
    
    Promise.any([
      delayed(800, 'a', true),
      delayed(500, 'b', true),
      delayed(250, 'c', true)
    ]).then(null, e => {
      console.log('All rejected (expecting array of failures):', e);
    });
    
    Promise.any([
      delayed(800, 'a'),
      delayed(500, 'b'),
      delayed(250, 'c', true),
      'd',
      'e'
    ]).then(e => {
      console.log('First non-promise (expecting d):', e);
    });
    
    // Because this is the only case to resolve synchronously,
    // its output should appear before the others
    Promise.any([]).then(e => {
      console.log('Empty input (expecting undefined):', e);
    });

提交回复
热议问题