我正在使用快速模塊在Node.JS中創建一個Restful API。在我的服務中,我向外部端點(服務器端)發出額外的http請求,並且需要將這些http請求中的數據返回給我的Web服務請求主體。Node.JS等待發出HTTP請求的REST服務的回調
我已經確認,如果我使用console.log
對Web服務進行的所有操作,我正在獲取我需要的數據。但是,當我嘗試將這些值返回給服務時,它們會返回空值。我知道這是因爲異步,回調並沒有等待http請求完成。
有沒有辦法讓這項工作?
我正在使用快速模塊在Node.JS中創建一個Restful API。在我的服務中,我向外部端點(服務器端)發出額外的http請求,並且需要將這些http請求中的數據返回給我的Web服務請求主體。Node.JS等待發出HTTP請求的REST服務的回調
我已經確認,如果我使用console.log
對Web服務進行的所有操作,我正在獲取我需要的數據。但是,當我嘗試將這些值返回給服務時,它們會返回空值。我知道這是因爲異步,回調並沒有等待http請求完成。
有沒有辦法讓這項工作?
通常的做法是使用async模塊。
npm install async
async
模塊具有原語來處理各種形式的異步事件。
在您的情況下,async#parallel
調用將允許您同時向所有外部API發出請求,然後將結果合併以返回給請求者。
由於您正在進行外部http請求,因此您可能會發現request模塊也很有用。
npm install request
使用request
和async#parallel
你的路由處理會是這個樣子......
var request = require('request');
var async = require('async');
exports.handler = function(req, res) {
async.parallel([
/*
* First external endpoint
*/
function(callback) {
var url = "http://external1.com/api/some_endpoint";
request(url, function(err, response, body) {
// JSON body
if(err) { console.log(err); callback(true); return; }
obj = JSON.parse(body);
callback(false, obj);
});
},
/*
* Second external endpoint
*/
function(callback) {
var url = "http://external2.com/api/some_endpoint";
request(url, function(err, response, body) {
// JSON body
if(err) { console.log(err); callback(true); return; }
obj = JSON.parse(body);
callback(false, obj);
});
},
],
/*
* Collate results
*/
function(err, results) {
if(err) { console.log(err); res.send(500,"Server Error"); return; }
res.send({api1:results[0], api2:results[1]});
}
);
};
您也可以瞭解其他回調測序方法here。
Node.js是關於回調的。除非API調用是同步的(很少發生並且不應該這樣做),否則永遠不會從這些調用返回值,而是使用回調方法中的結果進行回調,或者調用快速方法res.send
調用web請求是request.js
讓我們拿一個非常簡單的例子來調用谷歌。使用res.send,你express.js代碼可能看起來像:
var request = require('request');
app.get('/callGoogle', function(req, res){
request('http://www.google.com', function (error, response, body) {
if (!error && response.statusCode == 200) {
// from within the callback, write data to response, essentially returning it.
res.send(body);
}
})
});
或者,你可以傳遞一個回調來調用web請求的方法,並從該方法中調用該回調:
app.get('/callGoogle', function(req, res){
invokeAndProcessGoogleResponse(function(err, result){
if(err){
res.send(500, { error: 'something blew up' });
} else {
res.send(result);
}
});
});
var invokeAndProcessGoogleResponse = function(callback){
request('http://www.google.com', function (error, response, body) {
if (!error && response.statusCode == 200) {
status = "succeeded";
callback(null, {status : status});
} else {
callback(error);
}
})
}
例從丹尼爾的回答是:使用wait.for
wait.for https://github.com/luciotato/waitfor
其他答案的例子(異步),但使用Wait.for
var request = require('request');
var wait = require('wait.for');
exports.handler = function(req, res) {
try {
//execute parallel, 2 endpoints, wait for results
var result = wait.parallel.map(["http://external1.com/api/some_endpoint"
,"http://external2.com/api/some_endpoint"]
, request.standardGetJSON);
//return result
res.send(result);
}
catch(err){
console.log(err);
res.end(500,"Server Error")
}
};
//wait.for requires standard callbacks(err,data)
//standardized request.get:
request.standardGetJSON = function (options, callback) {
request.get(options,
function (error, response, body) {
//standardized callback
var data;
if (!error) data={ response: response, obj:JSON.parse(body)};
callback(error,data);
});
}
您需要接受回調。 – SLaks