ES6承诺等待K out N承诺解决

Foo*_*Bar 5 javascript ecmascript-6

var p1 = new Promise((resolve, reject) => { 
  setTimeout(resolve, 1000, 'one'); 
});
var p2 = new Promise((resolve, reject) => { 
  setTimeout(resolve, 2000, 'two'); 
});
var p3 = new Promise((resolve, reject) => {
  setTimeout(resolve, 3000, 'three');
});

Promise.all([p1,p2,p3]).then(values => { 
  console.log(values);
}, reason => {
  console.log(reason)
});
Run Code Online (Sandbox Code Playgroud)

我怎么能等待2个承诺才能完成?Promise.race()等待一个承诺完成.

编辑

我有许多承诺,我想要实现的是等待前k个承诺得到解决而不是触发一些事件.假设k <n

编辑 - 2

我相信,从n号承诺中可以成功解决k号承诺

JLR*_*she 9

(注意: Bluebird有一个内置的辅助函数,它正好用于此目的,并且与我的waitForN方法或多或少具有相同的行为,因此该选项始终可用)

我不相信ES6承诺有一个优雅的内置方式来做到这一点,但你可以定义以下相对较短的 现在有点长的帮助函数来处理这个问题.

编辑:添加了一个额外的辅助函数,其中包含结果中成功的promise的索引.

编辑:更新以拒绝拒绝次数达到无法成功解决的点.

编辑:更新为更优雅地使用,promises如果它是可迭代的并检查结果应立即解决的边缘情况(例如,如果n === 0)

function waitForN(n, promises) {
    let resolved = [];
    let failCount = 0;
    let pCount = 0;

    return new Promise((resolve, reject) => {
        const checkSuccess = () => {
            if (resolved.length >= n) { resolve(resolved); }
        };
        const checkFailure = () => {
            if (failCount + n > pCount) {
                reject(new Error(`Impossible to resolve successfully. n = ${n}, promise count = ${pCount}, failure count = ${failCount}`));
            }
        };

        for (let p of promises) {
            pCount += 1;

            Promise.resolve(p).then(r => {
                if (resolved.length < n) { resolved.push(r); }
                checkSuccess();
            }, () => {
                failCount += 1;
                checkFailure();
            });
        }

        checkFailure();
        checkSuccess();
    });
}

const waitForNWithIndices = (n, promises) =>
    waitForN(n, promises.map((p, index) => 
        Promise.resolve(p).then(result => ({ index, result }))
    ));

var p1 = new Promise((resolve, reject) => { 
  setTimeout(resolve, 1000, 'one'); 
});
var p2 = new Promise((resolve, reject) => { 
  setTimeout(resolve, 2000, 'two'); 
});
var p3 = new Promise((resolve, reject) => {
  setTimeout(resolve, 3000, 'three');
});
var p4 = new Promise((resolve, reject) => {
  setTimeout(resolve, 1500, 'four');
});

waitForN(2, [p1,p2,p3,p4]).then(values => { 
  console.log(values);
}, reason => {
  console.log(reason)
});

waitForNWithIndices(2, [p1,p2,p3,p4]).then(values => { 
  console.log(values);
}, reason => {
  console.log(reason)
});
Run Code Online (Sandbox Code Playgroud)

  • 没有提供任何方式来知道哪个结果是哪个.由于这个原因,可能有点难以使用.除此之外,看起来它会起作用. (2认同)