链多节点http请求

时间:2016-01-17 06:53:51

标签: javascript node.js http

我是节点新手,需要从我的代码中调用第三方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();

1 个答案:

答案 0 :(得分:30)

首先,由于其简单性,您需要查看request,这是HTTP请求最受欢迎的选择。

其次,我们可以将请求的简单性与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):虽然Promise把我们带到了中途,但是进一步的经验使我确信,当同步,异步代码和特别是控制之间存在很多混合时,Promise会变得混乱流动(例如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

UPDATE(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