【问题标题】:How to chain http request functions in serially [duplicate]如何串行链接http请求函数[重复]
【发布时间】:2019-08-11 10:42:46
【问题描述】:

我需要按顺序从三个 http 请求中获取响应。

我可以使用嵌套函数来做到这一点。我还需要使用全局范围内最后一个请求的响应,而嵌套解决方案无法做到这一点。

var request = require("request");

httpRequest1((getRequest1) => {
  console.log(getRequest1);
  httpRequest2((getRequest2) => {
    console.log(getRequest2);
    httpRequest3((getRequest3) => {
      console.log(getRequest3);
    });
  });
});

function httpRequest1 (callback){
var options = { method: 'POST',
  url: };
request(options, function (error, response, body) {
  if (error) throw new Error(error);
  callback (body);
});}

function httpRequest2(callback){
var options = { method: 'POST',
  url:  };
request(options, function (error, response, body) {
  if (error) throw new Error(error);
  callback(body);
});}

function httpRequest3(callback){
  var options = { method: 'POST',
    url: };
  request(options, function (error, response, body) {
    if (error) throw new Error(error);
    callback(body);
  });}

【问题讨论】:

  • 就是你怎么做的。如果您需要最终结果,请在回调中访问它。或者,查看 Promise。
  • 我推荐使用 PromoseAsync/Await 。避免回调,因为它可能会发生回调地狱。
  • 你将如何实现 Async/Await?当我尝试使用 Async/Await 时,我得到一个未定义的响应,好像它并没有真正等待请求完成。

标签: node.js asynchronous chaining


【解决方案1】:
function httpRequest1 (callback){
    var options = { method: 'POST', url: };
    return new Promise(function (resolve, reject) {
       request(options, function (error, response, body) {
         if (error) return reject(error);
        resolve(body);
       });
   });
}

function httpRequest2 (callback){
    var options = { method: 'POST', url: };
    return new Promise(function (resolve, reject) {
       request(options, function (error, response, body) {
         if (error) return reject(error);
        resolve(body);
       });
   });
}

function httpRequest3 (callback){
    var options = { method: 'POST', url: };

   return new Promise(function (resolve, reject) {
       request(options, function (error, response, body) {
         if (error) return reject(error);
         resolve(body);
       });
   });
}

承诺

httpRequest1()
 .then(body1 => 

    return httpRequest2();
 )
 .then(body2 => 

      return httpRequest3();
 )
 .then(body3 => 

 ).catch(error => {
     // error code
} );

异步/等待

function async getResponse() {
  try {
    const body1 = await httpRequest1();
    const body2 = await httpRequest2();
    const body3 = await httpRequest3();
  } catch (e) {
     console.log(e);
  } 
}

更新

Await 在正常功能下不起作用。如果您使用 await,您必须在 async 函数中使用它。如果您想从普通函数调用序列化异步函数,那么 promise 是更好的选择。但是你可以使用另一种方式。假设我们有一个像上面这样的异步函数并返回响应

function async getResponse() {
  try {
    const body1 = await httpRequest1();
    const body2 = await httpRequest2();
    const body3 = await httpRequest3();
    return { body1, body2, body3 }
  } catch (e) {
     console.log(e);
  } 
}
function normalFunction() {
    //  const res  = getResponse(); it will not work

    getResponse()
    .then(result  => {
      // you will get the result here
    })


}

在后台异步函数返回 promise Result 。这就是为什么我们可以这样写。

【讨论】:

  • 谢谢,Async/Await 代码有效,但我仍然有问题。如果我尝试在 Async 函数之外使用 body1-3 参数,它会在异步函数完成之前发生并且我知道它们是未定义的。
  • @GuyPerry 更新了,你可以看看
【解决方案2】:

您应该考虑更现代的async/await 模式并使用它来解决承诺。这将使您的代码对您自己和其他人更具可读性。

阅读此博客了解更多详细信息,特别是您案例中的“链式操作”部分:https://www.sitepoint.com/simplifying-asynchronous-coding-async-functions/

【讨论】:

    【解决方案3】:
    var request = require("request-promise");
    ( async () => {
        const getRequest1 = await httpRequest1();
        const getRequest2 = await httpRequest2();
        const getRequest3 = await httpRequest3();
    })();
    
    async function httpRequest1() {
        var options = {
            method: 'POST',
            url: ''
        };
        const body = await request(options)
        if (!body) throw "error";
        return body;
    }
    
    async function httpRequest2() {
        var options = {
            method: 'POST',
            url: ''
        };
        const body = await request(options)
        if (!body) throw "error";
        return body;
    }
    
    async function httpRequest3() {
        var options = {
            method: 'POST',
            url: ''
        };
        const body = await request(options)
        if (!body) throw "error";
        return body;
    }
    

    【讨论】:

      【解决方案4】:

      如果请求是独立的,你可以使用 Promise.all()。在调用 httpRequest2 之前,您不必等待 httpRequest1 的响应等等。

      https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2023-01-12
        • 2021-08-04
        • 2013-03-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多