等待请求完成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.createServer
callback中。