[英]How to inherit data in a chain of promises without creating a closure?
這是一個工作代碼示例:
request('http://foo.com/')
// Collect list of locations.
.then(function (response) {
let $ = response.data,
locations = [];
$('a[href^="/venues/"]').each(function () {
locations.push({
name: $(this).text(),
url: 'http://foo.com/' + $(this).attr('href')
});
});
return locations;
})
// Retrieve additional information about locations.
.map((location) => {
return request(location.url)
.then((response) => {
// Combine location specific information with the initial location information.
response;
location;
});
}, {
concurrency: 5
});
在上面的示例中,我向“ foo.com”發出請求,獲取位置列表,然后使用位置數據查詢“ foo.com”以獲取有關位置的其他信息。 最后,我將位置特定信息與初始位置信息結合在一起。
我對上面的代碼不滿意的是它不是平坦的。 如果特定於位置的查詢將需要其他異步信息,而其子查詢甚至將需要更多其他異步信息,則代碼將變成回調地獄。
我想將代碼轉換為平面結構,例如(偽代碼)
request('http://foo.com/')
// Collect list of locations.
.then(function (response) {
let $ = response.data,
locations = [];
$('a[href^="/venues/"]').each(function () {
locations.push({
name: $(this).text(),
url: 'http://foo.com/' + $(this).attr('href')
});
});
return locations;
})
// Retrieve additional information about locations.
.map((location) => {
return request(location.url);
}, {
concurrency: 5
})
// Filter list of responses.
.filter((response) => {
return response.incomingMessage.statusCode === 200;
})
// Combine location specific information with the initial location information.
.map((response) => {
// How to access "location" and "response"?
});
最好的方法是什么?
我能想到的唯一方法是擴大請求的響應,以獲取有關位置的其他數據,例如
.map((location) => {
return request('http://foo.com/' + location.nid)
.then((response) => {
return {
location: location,
response: response
};
});
}, {
concurrency: 5
})
這樣,整個Promise鏈或多或少保持平坦。
request('http://foo.com/')
// Collect list of locations.
.then(function (response) {
let $ = response.data,
locations = [];
$('a[href^="/venues/"]').each(function () {
locations.push({
nid: $(this).attr('href'),
name: $(this).text(),
url: 'http://foo.com/' + $(this).attr('href')
});
});
return locations;
})
// Retrieve additional information about locations.
.map((location) => {
return request('http://foo.com/' + location.nid)
.then((response) => {
return {
location: location,
response: response
};
});
}, {
concurrency: 5
})
// Filter list of responses.
.filter((response) => {
return response.response.incomingMessage.statusCode === 200;
})
.map((response) => {
// Combine location specific information with the initial location information.
response.response;
response.location;
});
如果在request()之后執行bind({}),則鏈中的函數將具有this
對象,可用於存儲事物。
例:
Promise.resolve('A').bind({}).then(function(value){
this.value = value;
return 5;
}).then(function(number) {
this.number = number;
}).then(function() {
console.log(this);
})
輸出:
{ value: 'A', number: 5 }
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.