【问题标题】:Chain multiple Node http request链接多个Node http请求
【发布时间】:2016-12-27 18:50:32
【问题描述】:

我是 node 新手,需要从我的代码中调用 3rd 方 api。我找到了如何通过使用来自此链接https://docs.nodejitsu.com/articles/HTTP/clients/how-to-create-a-HTTP-request 的 http.request 来执行此操作。我需要做的是调用两个不同的 api url,并在第二个调用中使用第一个调用的响应数据,这将只是一个 id 作为 resource2 上的参数。

我不知道如何将其中两个调用链接在一起而不造成重复的混乱。任何帮助将不胜感激。

var url1 = {
    host: 'www.domain.com',
    path: '/api/resourse1'
};

var url2 = {
    host: 'www.domain.com',
    path: '/api/resourse2/{id}'
};

var callback = function (response) {
    var str = '';

    response.on('data', function (chunk) {
        str += chunk;
    });

    response.on('end', function () {
        console.log(str);
    });
}

http.request(url1, callback).end();

【问题讨论】:

    标签: javascript node.js http


    【解决方案1】:

    首先,您需要看一下request,由于其简单性,它是 HTTP 请求最流行的选择。

    其次,我们可以将 request 的简单性与 Promises 的概念结合起来,连续发出多个请求,同时保持代码扁平化。
    使用request-promise

    var rp = require('request-promise')
    var url1 = {}
    var url2 = {}
    var url3 = {}
    
    
    rp(url1)
      .then(response => {
        // add stuff from url1 response to url2
        return rp(url2)
      })
      .then(response => {
        // add stuff from url2 response to url3
        return rp(url3)
      })
      .then(response => {
        // do stuff after all requests
    
        // If something went wrong
        // throw new Error('messed up')
      })
      .catch(err => console.log) // Don't forget to catch errors
    

    如您所见,我们可以根据需要添加任意数量的请求,并且代码将保持平坦和简单。作为奖励,我们还能够添加错误处理。使用传统的回调,你必须为每个回调添加错误处理,而在这里我们只需要在 Promise 链的末尾做一次。

    更新 (09/16): 虽然 Promises 将我们带到了一半,但进一步的经验使我确信,当同步、异步代码,尤其是控制之间存在大量混合时,仅 Promises 就会变得混乱流(例如 if-else)。解决这个问题的规范方法是使用async/await,但是它仍在开发中,需要转译。因此,generators 是下一个最佳解决方案。

    使用co

    var co = require('co')
    var rp = require('request-promise')
    var url1 = {}
    var url2 = {}
    var url3 = {}
    
    co(function* () {
      var response
      response = yield rp(url1)
      // add stuff from url1 response to url2
      response = yield rp(url2)
      // add stuff from url2 response to url3
      response = yield rp(url3)
    
      // do stuff after all requests
    
      // If something went wrong
      // throw new Error('messed up')
    })
    .catch(err => console.log) // Don't forget to catch errors
    

    更新 (12/16):现在最新版本的节点 (7.2.1) 在 --harmony 标志后面支持 async/await,您可以这样做:

    const rp = require('request-promise')
    const url1 = {}
    const url2 = {}
    const url3 = {}
    
    async function doRequests() {
      let response
      response = await rp(url1)
      // add stuff from url1 response to url2
      response = await rp(url2)
      // add stuff from url2 response to url3
      response = await rp(url3)
    
      // do stuff after all requests
    
      // If something went wrong
      // throw new Error('messed up')
    }
    
    doRequests()
    .catch(err => console.log) // Don't forget to catch errors
    

    【讨论】:

    • 大致就是我输入的答案。使用 request 和使用 Promises 都是很好的建议。
    • 谢谢,但我得到的表达式语句不是分配或调用。除了请求承诺之外,我还需要添加另一个库吗? .then(响应 => {
    • 嗯,您不需要任何其他库。尝试用 ES5 编写,您的节点版本可能不支持粗箭头符号。 .then(function(response) {...})
    • @PrashanthChandra 谢谢!做到了
    猜你喜欢
    • 1970-01-01
    • 2015-11-13
    • 1970-01-01
    • 2015-04-22
    • 1970-01-01
    • 2017-10-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多