等待请求完成Node.js

我目前有一个问题,如何在返回任何数据之前等待请求完成。 我不相信我可以用Callback做到这一点,我还没有find一个使用EventEmitter来做这件事的好方法。 我不能使用callback的原因是因为我的stream程目前的工作是这样的。

请求进入服务器>生成XML>联系远程API的详细信息,以完成生成XML>完成生成XML>返回请求到客户端

我目前的代码看起来非常类似于下面的代码。

networking服务器:

var xml = require('./XMLGenerator'); response.writeHead(200, {'Content-Type': 'text/xml'}); response.write(xml.generateXML()); response.end(); 

XML生成器:

 function generateXML(){ // Code to generate XML var API = require('./API'); var response = API.getItems("5"); for(var i = 1; i <= response.length; i++) { // more code to generate further XML using the API response } // Finish generating and return the XML } 

API抓取器:

 function getItems(sort_by, amount) { var request = require("request") var url = "https://url.com/api/get_items.json?amount=" + amount; request({ url: url, json: true }, function (error, response, body) { console.log('we got here!'); if (!error && response.statusCode === 200) { var items = body.data.items; console.log(items); return items; } else { console.log("Error connecting to the API: " + url); return; } }) } 

当直接运行代码并进行testing时,它会返回“undefined”,表示请求尚未完成。 我只需要知道一种方法,使XML生成器等待请求完成,然后继续生成。 (在我input的psudeo代码中可能存在一些小错误,因为它不是源代码中的精确复制粘贴,但是它在这个stream程中起作用)

我只是使用不好的做法,或者这是我应该尝试的正确方法?

编辑:问题是不加载模块/ API文件,加载完全正常。 问题是请求需要大约2秒才能完成,并且该请求在请求完成之前继续运行。

你需要使用callback。 将您的API抓取器更改为:

 function getItems(amount, callback) { // some code... request({ url: url, json: true }, function (error, response, body) { // some code... if (!error && response.statusCode === 200) { // some code callback(items); <-- pass items to the callback to "return" it } }) } 

然后更改xml生成器以接受callback:

 function generateXML(callback){ // Code to generate XML var API = require('./API'); API.getItems("5",function(response){ for(var i = 1; i <= response.length; i++) { // more code to generate further XML using the API response } // Finish generating and return the XML callback(xml_result); // <-- again, "return" the result via callback }); } 

然后在你的服务器代码中做:

 var xml = require('./XMLGenerator'); response.writeHead(200, {'Content-Type': 'text/xml'}); xml.generateXML(function(xmlstring){ response.write(xmlstring); response.end(); }); 

做这些更改,因为request是asynchronous的,使用callback。

 API.getItems("5", function(rs){ var response = rs; for(var i = 1; i <= response.length; i++) { // more code to generate further XML using the API response } // Finish generating and return the XML } }); ... function getItems(sort_by, amount, callback) {... ... callback(items); //Instead of return items; ... 

你不能从async调用return ,你的情况就是request模块。 在这种情况下,您可以使用承诺callbacks 。 这是一个callback的解决scheme。

它返回undefined的实际问题是它不等待var response = API.getItems("5"); 完全执行并执行下一行,因此您得到的response undefined 。 我希望你明白这一点。

我也希望

 response.writeHead(200, {'Content-Type': 'text/xml'}); response.write(xml.generateXML()); response.end(); 

在某个API或http.createServercallback中。