Javascript 等待请求完成 Node.js

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/30389764/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 05:07:34  来源:igfitidea点击:

Wait for request to finish Node.js

javascriptxmlnode.js

提问by OstlerDev

I am currently having an issue with figuring out how to wait for the request to finish before returning any data. I do not believe I can do this with a Callback and I have not been able to figure out a good way of using the EventEmitter to do it. The reason I cannot use a callback is because my flow currently works like this.

我目前在弄清楚如何在返回任何数据之前等待请求完成时遇到问题。我不相信我可以通过回调来做到这一点,而且我无法找到使用 EventEmitter 来做到这一点的好方法。我不能使用回调的原因是我的流程目前是这样工作的。

Request comes into server > Generate XML > Contact remote API for details to finish generating XML > Finish Generating XML > Return request to client

请求进入服务器 > 生成 XML > 联系远程 API 以获取详细信息以完成生成 XML > 完成生成 XML > 将请求返回给客户端

The code I currently have looks very similar to the code included below.

我目前拥有的代码看起来与下面包含的代码非常相似。

Web Server:

网络服务器:

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

XML Generator:

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 Grabber:

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;
    }
})
}

When running the code and testing directly it returns "undefined" meaning that the request has not been made yet. I just need to know a way to make the XML generator wait for the request to finish before continuing on with the generation. (there may be minor errors in the psudeo code I typed up as it is not an exact copy paste from the source, it does however work in this flow)

当运行代码并直接测试时,它返回“未定义”,表示尚未发出请求。我只需要知道一种让 XML 生成器在继续生成之前等待请求完成的方法。(我输入的伪代码中可能存在小错误,因为它不是来自源代码的精确复制粘贴,但它确实在此流程中工作)

Am I just using bad practices, or is this the correct way that I should be attempting this?

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

EDIT: The problem is not loading the module/API file, that loads perfectly fine. The problem is that the request takes about 2 seconds to complete, and that node moves on before the request completes.

编辑:问题不在于加载模块/API 文件,加载非常好。问题是请求大约需要 2 秒才能完成,并且该节点在请求完成之前继续前进。

回答by slebetman

You need to use callbacks. Change your API grabber to this:

您需要使用回调。将您的 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
   }
})
}

Then change the xml generator to also accept callbacks:

然后将 xml 生成器更改为也接受回调:

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
});
}

Then in your server code do:

然后在您的服务器代码中执行以下操作:

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

回答by Zee

Do these changes since requestis async, use callbacks.

执行这些更改,因为request是异步的,请使用回调。

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;

...

You cannot returnfrom an asynccall, which is requestmodule in your case. In such cases you can either use promisesor callbacks. This is a solution with callback.

你不能return从一个async电话,这是request你的情况模块。在这种情况下,您可以使用promisecallbacks. 这是一个带有回调的解决方案。

The actual problem of it returning undefinedis it doesnot wait for var response = API.getItems("5");to execute completely and executes the next line and hence you get responseas undefined. I hope you get the point.\

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

Also I hope

我也希望

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

is somewhere inside some callback of an API or http.createServer.

位于 API 或http.createServer.