好的,我正在尝试使用请求模块向API端点发出两个或更多请求.我正在渲染一个HTML文件,并使用以下代码将返回的JSON传递给把手模板:
res.render('list.html', { title: 'List', data: returnedJSON }
然后我可以很容易地在我的把手模板中迭代这个JSON.
我遇到的问题是,我现在需要使用多个数据源,其中类别列表将根据JSON响应类别和员工JSON响应中的Staff列表构建.我想要一个简单的解决方案,我可以做到这一点,但扩展它使用任意数量的数据源.
下面是我对一个数据源的完整代码片段:
request({ url: 'https://api.com/categories', headers: { 'Bearer': 'sampleapitoken' } }, function(error, response, body) { if(error || response.statusCode !== 200) { // handle error } else { var json = JSON.parse(body); res.render('list.html', { title: 'Listing', data: json }); } });
这适用于一个端点,但如前所述,我现在需要使用多个请求并拥有多个数据源,例如:
request({ url: ['https://api.com/categories','https://api.com/staff'], headers: { 'Bearer': 'sampleapitoken' } }, function(error, response, body1, body2) { if(error || response.statusCode !== 200) { // handle error } else { var json1 = JSON.parse(body1); var json2 = JSON.parse(body2); res.render('list.html', { title: 'Listing', staff: json1, categories: json2 }); } });
我很欣赏以上不是那样的,但我希望这可以帮助传达我想要实现的目标.
提前致谢 :)
您可以使用异步库映射请求对象并将它们传递给实际请求,并在一次回调中返回所有结果.
var async = require("async"); var request = require("request"); // create request objects var requests = [{ url: 'https://api.com/categories', headers: { 'Bearer': 'sampleapitoken' } }, { url: 'https://api.com/staff', headers: { 'Bearer': 'sampleapitoken' } }]; async.map(requests, function(obj, callback) { // iterator function request(obj, function(error, response, body) { if (!error && response.statusCode == 200) { // transform data here or pass it on var body = JSON.parse(body); callback(null, body); } else { callback(error || response.statusCode); } }); }, function(err, results) { // all requests have been made if (err) { // handle your error } else { console.log(results); for (var i = 0; i < results.length; i++) { // request body is results[i] } } });
然而,更简单的方法是利用promises,这可以通过bluebird和promisifying请求lib来完成,或者使用已经公布的请求lib request-promise.您仍然希望包含一个promise/A + lib来异步映射结果.
var Promise = require("bluebird"); var request = require('request-promise'); // create request objects var requests = [{ url: 'https://api.com/categories', headers: { 'Bearer': 'sampleapitoken' } }, { url: 'https://api.com/staff', headers: { 'Bearer': 'sampleapitoken' } }]; Promise.map(requests, function(obj) { return request(obj).then(function(body) { return JSON.parse(body); }); }).then(function(results) { console.log(results); for (var i = 0; i < results.length; i++) { // access the result's body via results[i] } }, function(err) { // handle all your errors here });
值得注意的是,所有最新版本的节点和浏览器都支持开箱即用的Promise,这可以在没有外部库的情况下实现.