Hen*_*los 4 javascript promise bluebird
让我们假设我有10个Promises正在运行,Promise.map()它的默认并发设置为3.
如果前3个承诺中的任何一个被拒绝,其他7个承诺是否会被启动?
蓝鸟的文档的map()状态如下:
等待映射器函数返回的Promise,并且在所有映射的promise都已满足之前,返回的promise不会实现.如果数组中的任何promise被拒绝,或者mapper函数返回的任何promise都被拒绝,那么返回的promise也会被拒绝.
它只表明,如果一切都满足,那么等待内心的承诺,但我不清楚如果其中任何一个遭到拒绝会发生什么.
我知道map函数的规范定义是输出的长度与输入的大小相同,但我不确定Bluebird是否尊重它.
从字面上看,蓝鸟的立刻Promise.prototype.map回归.
执行此操作时,它会返回Promise可能无法立即解决的问题.我想你真的想知道这个承诺是如何表现的,并且有一些事情需要解决:
如果前3个承诺中的任何一个被拒绝,其他7个承诺是否会被启动?
是.Promise在您创建时"已启动"(即已安排).其他7人将尝试解决或可能足以让你需要假设他们会这样做.
想象一下,如果浏览器只允许4个HTTP连接到服务器并且您发出10个请求.那些第一个(失败的)3将和一个朋友一起被发送,他可能不会失败但肯定会跑.
你应该假设所有的承诺都会调用他们的身体.
它只表明,如果一切都满足,那么等待内心的承诺,但我不清楚如果其中任何一个遭到拒绝会发生什么.
这很容易测试:
const Promise = require('bluebird');
function delayReject(delay, err) {
return new Promise((res, rej) => {
console.log('waiting to reject', err);
setTimeout(() => rej(err), delay);
});
}
function delayValue(delay, val) {
return new Promise((res, rej) => {
console.log('waiting to resolve', val);
setTimeout(() => res(val), delay);
});
}
const promises = [1, 2, 3, 4, 5, 6, 7, 8, 9].map(it => {
if (it % 3 === 0) {
return delayReject(50, it);
} else {
return delayValue(50, it);
}
});
Promise.map(promises, v => {
console.log('mapping', v);
return -v;
}).then(it => {
console.log('mapped', it);
}).catch(err => {
console.log('error', err);
});
Run Code Online (Sandbox Code Playgroud)
我的输出node v6.8.1是:
ssube@localhost ~/questions/40619451 $ > node early-exit.js
waiting to resolve 1
waiting to resolve 2
waiting to reject 3
waiting to resolve 4
waiting to resolve 5
waiting to reject 6
waiting to resolve 7
waiting to resolve 8
waiting to reject 9
mapping 1
mapping 2
error 3
Run Code Online (Sandbox Code Playgroud)
正如您所料,所有承诺都已安排并运行,但map在第一次失败后,它们会停止运行.
Bluebird文档提到:
尽可能快地调用给定项的映射器函数,也就是说,当满足输入数组中该项的索引的承诺时.这并不意味着结果数组具有随机顺序的项,这意味着
.map可以用于并发协调.all.
这表明映射项的顺序可能不会持久化,就像在上面的示例中一样.我们可以通过在延迟中添加一些噪声来测试它:
const Promise = require('bluebird');
function delayNoise(n) {
return n + Math.floor(Math.random() * 50);
}
function delayReject(delay, err) {
return new Promise((res, rej) => {
console.log('waiting to reject', err);
setTimeout(() => rej(err), delayNoise(delay));
});
}
function delayValue(delay, val) {
return new Promise((res, rej) => {
console.log('waiting to resolve', val);
setTimeout(() => res(val), delayNoise(delay));
});
}
const promises = [1, 2, 3, 4, 5, 6, 7, 8, 9].map(it => {
if (it % 3 === 0) {
return delayReject(50, it);
} else {
return delayValue(50, it);
}
});
Promise.map(promises, v => {
console.log('mapping', v);
return -v;
}).then(it => {
console.log('mapped', it);
}).catch(err => {
console.log('error', err);
});
Run Code Online (Sandbox Code Playgroud)
运行会产生更有趣的结果:如果第一个承诺拒绝,则地图结束并且不会尝试映射其他地图.正如你猜测的那样,它会发生短路.
我取得了与@ssube 的答案非常相似的结果。
我有 10 个承诺,这些承诺将在超时时间增加后得到解决或拒绝。第四个(因为数组是从 0 开始的)被拒绝。
const Promise = require('bluebird')
function delay(timeout, err, i) {
return new Promise(function (resolve, reject) {
if (err) {
setTimeout(function () {
console.log('Rejected', err.message)
reject(err)
}, timeout)
} else {
setTimeout(function () {
console.log('Resolved', i)
resolve(i)
}, timeout)
}
})
}
const promises = Array.apply(null, {length: 10})
.map(Function.call, Number)
.map(function (it) {
if (it === 3) {
return delay(500 * it, new Error(it))
} else {
return delay(500 * it, null, it)
}
})
Promise.map(promises, function (p) {
console.log('Mapping', p)
return p.toString()
})
.then(function (it) {
console.log('All resolved', it)
})
.catch(function (err) {
console.log('Error', err.message)
})
Run Code Online (Sandbox Code Playgroud)
这将产生:
> Resolved 0
> Mapping 0
> Resolved 1
> Mapping 1
> Resolved 2
> Mapping 2
> Rejected 3
> Error 3
> Resolved 4
> Resolved 5
> Resolved 6
> Resolved 7
> Resolved 8
> Resolved 9
Run Code Online (Sandbox Code Playgroud)
因此,行为如下:
Promise.map每当被映射的承诺之一被拒绝时,就会短路。map对于任何后续的承诺,永远不会执行回调 in 。Error 3出现在故意放慢的承诺之前。| 归档时间: |
|
| 查看次数: |
1245 次 |
| 最近记录: |