运行并行承诺并在其中两个解决时放弃休息

时间:2018-10-15 23:14:49

标签: node.js promise

我想同时从10个不同的服务器收集数据,当我收到其中2个响应时,我想忽略/跳过其他服务器。我用promise.all()解决了这个问题,当我得到2个响应时,我调用reject而不是resolve并在catch()中完成工作。但这对我来说似乎有点棘手,还有什么更好的方法吗?

3 个答案:

答案 0 :(得分:1)

这里与@Neverever建议的BlueBird Promise.some方法类似

function awaitSome(promises, count) {
    if (!Array.isArray(promises) || promises.length < count) {
        return Promise.reject();
    }

    return new Promise((resolve, reject) => {
        const results = [];
        const errors = [];
        let completed = false;

        promises.forEach((p) => {
            p.then((result) => {
                if (!completed) {
                    results.push(result);
                    if (results.length === count) {
                        completed = true;
                        resolve(results);
                    }
                }
            }).catch((err) => {
                if (!completed) {
                    errors.push(err);
                    if (promises.length - errors.length < count) {
                        completed = true;
                        reject(errors);
                    }
                }
            });
        });
    });
}

以及用法是谁

awaitSome(
    [
        Promise.resolve(1),
        Promise.reject(1),
        Promise.resolve(1),
        Promise.resolve(1)
    ],
    2
)
    .then((results) => {
        console.log(results);
    })
    .catch((errors) => {
        console.error(errors);
    });

答案 1 :(得分:0)

您可以构造两个<key>NSAppTransportSecurity</key> <dict> <key>NSExceptionDomains</key> <dict> <key>yourdomain.com</key> <dict> <key>NSExceptionAllowsInsecureHTTPLoads</key> <true/> </dict> </dict> </dict> 并将它们的Promises放入数组中。当一个响应返回时,resolvepop()中的一个并调用它。重复第二个响应。由于该数组现在为空,因此可以忽略进一步的响应。

然后,您可以在两个构造的Promises上调用resolve,这将在两个Promise.all被调用时解决。

resolve

您可以在上面的代码中看到,尽管最近的第3到第10个API调用都可以解决,但是const api = () => new Promise(res => { const timeout = Math.random() * 3000; setTimeout(() => { console.log('resolving ' + timeout); res(timeout); }, timeout) }); const resolves = []; const prom1 = new Promise(resolve => resolves.push(resolve)); const prom2 = new Promise(resolve => resolves.push(resolve)); for (let i = 0; i < 10; i++) { api().then(res => { if (!resolves.length) return; resolves.pop()(res); }); } Promise.all([prom1, prom2]) .then(([res1, res2]) => { console.log('got 2 responses', res1, res2); });可以在第一个和第二个最快的解决方法中尽快解决。

答案 2 :(得分:0)

您应该看看BlueBird Promise.some

http://bluebirdjs.com/docs/api/promise.some.html

  

给出一个Iterable(数组是Iterable),或一个Iterable的一个Promise,它产生一个Promise(或Promise和值的混合),将Iterable中的所有值迭代到一个数组中,并返回一个已实现的Promise一旦在数组中实现了计数承诺。履行值是一个数组,其中包含按履行顺序计数的值。

     

此示例对4个名称服务器执行ping操作,并在控制台上记录最快的2个名称服务器:

Promise.some([
    ping("ns1.example.com"),
    ping("ns2.example.com"),
    ping("ns3.example.com"),
    ping("ns4.example.com")
], 2).spread(function(first, second) {
    console.log(first, second);
});