这段代码中嵌套的承诺的目的是什么?
What is the purpose of the nested promise in this code?
我正在尝试熟悉 Promises 及其工作原理。虽然这对我来说是一个新概念,但我相对确定我可以理解其中的大部分内容。特别是,我一直在查看 BlueBird 库并按照我的方式完成示例。但是页面上有一个代码片段我无法完全理解。
Promise.promisifyAll(needle);
var options = {};
var current = Promise.resolve();
Promise.map(URLs, function(URL) {
current = current.then(function () {
return needle.getAsync(URL, options);
});
return current;
}).map(function(responseAndBody){
return JSON.parse(responseAndBody[1]);
}).then(function (results) {
return processAndSaveAllInDB(results);
}).then(function(){
console.log('All Needle requests saved');
}).catch(function (e) {
console.log(e);
});
在这段代码中,我了解到 needle
库正在被承诺。我想我说 current
被设置为一个空洞的承诺是正确的。
我的问题是关于
current = current.then(function () {
return needle.getAsync(URL, options);
});
return current;
代码。如果 needle 已被 promised,将其嵌套在另一个 promise 中的目的是什么?
这是一种对异步调用进行排队并同时将它们交给 map
函数以便生成所有结果数组的承诺的可疑方法。
那么它有什么作用呢?单独排队通常是 done using reduce
,带有 current
累加器的循环也是如此。它以空承诺开始,并为数组中的每个 url 重复链接一个回调;就像这段代码一样:
var current = Promise.resolve().then(function() {
return needle.getAsync(URL[0], options);
}).then(function() {
return needle.getAsync(URL[1], options);
}).then(function() {
return needle.getAsync(URL[2], options);
}) …
但是,在 map
循环中使用它实际上会生成一个单一承诺数组,例如
var promises = [];
promises[0] = Promise.resolve().then(function() {
return needle.getAsync(URL[0], options);
});
promises[1] = promises[0].then(function() {
return needle.getAsync(URL[1], options);
});
promises[2] = promises[1].then(function() {
return needle.getAsync(URL[2], options);
});
…
我要么使用 reduce
方式,从 Promise.resolve([])
开始逐步添加到结果数组,要么写一个专用的 scan
(或 mapAccum
, 无论你想给它起什么名字) 函数并将其与 Promise.all
.
结合使用
或者更好,只需使用 Bluebird 的内置 {concurrency: 1}
option for Promise.map
!
Bergi 写了一个很好的答案,您应该阅读。以下是我使用 .each
:
编写代码的方式
var get = Promise.promisify(needle.get);
Promise.each(URLs, get). // make the requests
map(function(x){ return JSON.parse(x[1])} ). // parse response as json
then(processAndSaveAllInDB).
then(function(){ console.log("All Needle requests saved"); }).
请注意,您不需要 catch
,因为在这种情况下,Bluebird 会发现未处理的拒绝并为您报告。
通常当人们执行上面的代码时,他们会关心顺序,尽管原始代码中不能保证顺序(map 改变了 bluebird 2 中的行为更快但不能保证排队顺序)。
我正在尝试熟悉 Promises 及其工作原理。虽然这对我来说是一个新概念,但我相对确定我可以理解其中的大部分内容。特别是,我一直在查看 BlueBird 库并按照我的方式完成示例。但是页面上有一个代码片段我无法完全理解。
Promise.promisifyAll(needle);
var options = {};
var current = Promise.resolve();
Promise.map(URLs, function(URL) {
current = current.then(function () {
return needle.getAsync(URL, options);
});
return current;
}).map(function(responseAndBody){
return JSON.parse(responseAndBody[1]);
}).then(function (results) {
return processAndSaveAllInDB(results);
}).then(function(){
console.log('All Needle requests saved');
}).catch(function (e) {
console.log(e);
});
在这段代码中,我了解到 needle
库正在被承诺。我想我说 current
被设置为一个空洞的承诺是正确的。
我的问题是关于
current = current.then(function () {
return needle.getAsync(URL, options);
});
return current;
代码。如果 needle 已被 promised,将其嵌套在另一个 promise 中的目的是什么?
这是一种对异步调用进行排队并同时将它们交给 map
函数以便生成所有结果数组的承诺的可疑方法。
那么它有什么作用呢?单独排队通常是 done using reduce
,带有 current
累加器的循环也是如此。它以空承诺开始,并为数组中的每个 url 重复链接一个回调;就像这段代码一样:
var current = Promise.resolve().then(function() {
return needle.getAsync(URL[0], options);
}).then(function() {
return needle.getAsync(URL[1], options);
}).then(function() {
return needle.getAsync(URL[2], options);
}) …
但是,在 map
循环中使用它实际上会生成一个单一承诺数组,例如
var promises = [];
promises[0] = Promise.resolve().then(function() {
return needle.getAsync(URL[0], options);
});
promises[1] = promises[0].then(function() {
return needle.getAsync(URL[1], options);
});
promises[2] = promises[1].then(function() {
return needle.getAsync(URL[2], options);
});
…
我要么使用 reduce
方式,从 Promise.resolve([])
开始逐步添加到结果数组,要么写一个专用的 scan
(或 mapAccum
, 无论你想给它起什么名字) 函数并将其与 Promise.all
.
或者更好,只需使用 Bluebird 的内置 {concurrency: 1}
option for Promise.map
!
Bergi 写了一个很好的答案,您应该阅读。以下是我使用 .each
:
var get = Promise.promisify(needle.get);
Promise.each(URLs, get). // make the requests
map(function(x){ return JSON.parse(x[1])} ). // parse response as json
then(processAndSaveAllInDB).
then(function(){ console.log("All Needle requests saved"); }).
请注意,您不需要 catch
,因为在这种情况下,Bluebird 会发现未处理的拒绝并为您报告。
通常当人们执行上面的代码时,他们会关心顺序,尽管原始代码中不能保证顺序(map 改变了 bluebird 2 中的行为更快但不能保证排队顺序)。