我想同时从10个不同的服务器收集数据,当我收到其中2个响应时,我想忽略/跳过其他服务器。我用promise.all()解决了这个问题,当我得到2个响应时,我调用reject而不是resolve并在catch()中完成工作。但这对我来说似乎有点棘手,还有什么更好的方法吗?
答案 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
放入数组中。当一个响应返回时,resolve
个pop()
中的一个并调用它。重复第二个响应。由于该数组现在为空,因此可以忽略进一步的响应。
然后,您可以在两个构造的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);
});