我在帖子中提出了以下问题:Chaining Requests using BlueBird/ Request-Promise
我对承诺很新,所以请原谅天真。我成功地实现了这段代码:
var BPromise = require('bluebird');
var rp = require('request-promise');
BPromise.all([
rp(optionsForRequest1),
rp(optionsForRequest2)
])
.spread(function (responseRequest1, responseRequest2) {
// Proceed with other calls...
})
.catch(function (err) {
// Will be called if at least one request fails.
});
但就我而言,每次特定的网址都不同。我想获取新的URL数组,为每个URL构造选项对象,然后是rp()。
当我逐字地构造一个像这样的数组 - var freshArray =[rp({Uri1 w/options}), rp({Uri2 w/options}), etc]
并将其粘贴到上面的.all()时 - 没有运气。我认为rp()的实现独立于BPromise.all调用?
如何动态地将构造的promise数组嵌入到上面的代码中?
答案 0 :(得分:1)
我不确定你想做什么,但会
BPromise.all([optionsForRequest1, optionsForRequest2].map((url) => {
const urlWithOptions = someFunction(url);
return rp(urlWithOptions);
})])
.spread(function (responseRequest1, responseRequest2) {
// Proceed with other calls...
})
.catch(function (err) {
// Will be called if at least one request fails.
});
工作?如果是这样,您甚至可以使用地图中的(url) => rp(someFunction(url))
缩短它
=== edit ===
(x) => y
是es6的简写版,大部分时间都是function(x) { return y; }
(x) => { ... return y; }
是一种类似的简写,可让您拥有中间变量。更多关于互联网上的es6 :)像here
.map
是在数组上定义的函数。它将函数应用于每个元素,因此[1, 2].map((x) => x + 1)
返回[2, 3]
所以代码就像
var urls = [optionsForRequest1, optionsForRequest2];
var urlsWithOptions = [];
for (var k in urls) {
urlsWithOptions.push(someFunction(urls[k]));
}
BPromise.all(urlsWithOptions)
...
答案 1 :(得分:1)
如果您正在使用Bluebird并且您想要与异步操作并行处理任意数组,那么您应该使用Bluebird的Promise.map()
,因为它是这种情况下的快捷方式:
var requestOptionsArray = [{...}, {...}, {...}];
Promise.map(requestOptionsArray, function(item) {
return rp(item);
}).then(function(results) {
// all results here
}).catch(function(err) {
// error here
});
Promise.map()
是迭代数组的快捷方式,在数组中的每个项目上调用promise生成函数,累积所有promise,然后使用所有promises调用Promise.all()
。而不是所有这些步骤,它只需一步即可完成所有这些步骤。最终结果是一系列有序结果。这些操作都是并行运行的。
如果要序列化操作,可以使用Promise.mapSeries()
。如果您想同时控制有多少请求在飞行中,则可以将{concurrency: 3}
选项传递给Promise.map()
(对于不会一次性请求过多请求的目标服务器或对避免某些请求有用的目标服务器非常有用)在某些情况下,您可能会在一次请求过多的情况下限制费率。)