Javascript 如何使用 Promise 链接和共享先前的结果
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/28714298/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to chain and share prior results with Promises
提问by user1513388
I'm using the bluebird library and need to make a series of HTTP requests and need to some of the response data to the next HTTP request. I've built a function that handles my requests called callhttp(). This takes a url and the body of a POST.
我正在使用 bluebird 库并且需要发出一系列 HTTP 请求并且需要一些响应数据到下一个 HTTP 请求。我构建了一个函数来处理我的请求,名为callhttp(). 这需要一个 url 和一个 POST 的正文。
I'm calling it like this:
我这样称呼它:
var payload = '{"Username": "joe", "Password": "password"}';
var join = Promise.join;
join(
callhttp("172.16.28.200", payload),
callhttp("172.16.28.200", payload),
callhttp("172.16.28.200", payload),
function (first, second, third) {
console.log([first, second, third]);
});
The first request gets an API key which needs to be passed to the second request and so on. How do get the response data from the first request?
第一个请求获取需要传递给第二个请求的 API 密钥,依此类推。如何从第一个请求中获取响应数据?
UPDATE
更新
This is the callhttpfunction:
这是callhttp函数:
var Promise = require("bluebird");
var Request = Promise.promisify(require('request'));
function callhttp(host, body) {
var options = {
url: 'https://' + host + '/api/authorize',
method: "POST",
headers: {
'content-type': 'application/json'
},
body: body,
strictSSL: false
};
return Request(options).spread(function (response) {
if (response.statusCode == 200) {
// console.log(body)
console.log(response.connection.getPeerCertificate().subject.CN)
return {
data: response.body
};
} else {
// Just an example, 200 is not the only successful code
throw new Error("HTTP Error: " + response.statusCode );
}
});
}
回答by jfriend00
There are a few models for dependent promises and passing data from one to the next. Which one works best depends upon whether you only need the previous data in the next call or whether you need access to all prior data. Here are several models:
有几个模型用于从一个到下一个依赖承诺和传递数据。哪个效果最好取决于您是否只需要在下一次调用中使用先前的数据,或者是否需要访问所有先前的数据。这里有几个模型:
Feed Result of One to the Next
一个到下一个的饲料结果
callhttp(url1, data1).then(function(result1) {
// result1 is available here
return callhttp(url2, data2);
}).then(function(result2) {
// only result2 is available here
return callhttp(url3, data3);
}).then(function(result3) {
// all three are done now, final result is in result3
});
Assign Intermediate Results to Higher Scope
将中间结果分配给更高的范围
var r1, r2, r3;
callhttp(url1, data1).then(function(result1) {
r1 = result1;
return callhttp(url2, data2);
}).then(function(result2) {
r2 = result2;
// can access r1 or r2
return callhttp(url3, data3);
}).then(function(result3) {
r3 = result3;
// can access r1 or r2 or r3
});
Accumulate Results in One Object
在一个对象中累积结果
var results = {};
callhttp(url1, data1).then(function(result1) {
results.result1 = result1;
return callhttp(url2, data2);
}).then(function(result2) {
results.result2 = result2;
// can access results.result1 or results.result2
return callhttp(url3, data3);
}).then(function(result3) {
results.result3 = result3;
// can access results.result1 or results.result2 or results.result3
});
Nest, so all Previous Results Can Be Accessed
Nest,因此可以访问所有以前的结果
callhttp(url1, data1).then(function(result1) {
// result1 is available here
return callhttp(url2, data2).then(function(result2) {
// result1 and result2 available here
return callhttp(url3, data3).then(function(result3) {
// result1, result2 and result3 available here
});
});
})
Break the Chain into Independent Pieces, Collect Results
将链条分解成独立的部分,收集结果
If some parts of the chain can proceed independently, rather than one after the other, then you can launch them separately and use Promise.all()to know when those multiple pieces are done and you then will have all the data from those independent pieces:
如果链的某些部分可以独立进行,而不是一个接一个,那么您可以单独启动它们并使用它Promise.all()来了解这些多个部分何时完成,然后您将拥有来自这些独立部分的所有数据:
var p1 = callhttp(url1, data1);
var p2 = callhttp(url2, data2).then(function(result2) {
return someAsync(result2);
}).then(function(result2a) {
return someOtherAsync(result2a);
});
var p3 = callhttp(url3, data3).then(function(result3) {
return someAsync(result3);
});
Promise.all([p1, p2, p3]).then(function(results) {
// multiple results available in results array
// that can be processed further here with
// other promises
});
Sequence with awaitin ES7
awaitES7 中的序列
Since the promise chain is just a mechanism for sequencing asynchronous operations, in ES7, you can also use awaitand then the intermediate results are all available in the same scope (perhaps simpler than the separate scopes of the chained .then()handlers):
由于promise链只是对异步操作进行排序的一种机制,在ES7中,你也可以使用await然后中间结果都在同一个范围内可用(也许比链式.then()处理程序的单独范围更简单):
async function someFunction(...) {
const r1 = await callhttp(url1, data1);
// can use r1 here to formulate second http call
const r2 = await callhttp(url2, data2);
// can use r1 and r2 here to formulate third http call
const r3 = await callhttp(url3, data3);
// do some computation that has access to r1, r2 and r3
return someResult;
}
someFunction(...).then(result => {
// process final result here
}).catch(err => {
// handle error here
});

