Superagent在异步瀑布中移动响应回调位置

时间:2014-05-03 06:05:15

标签: node.js coffeescript node-async superagent

我有一个简单的superagent / async瀑布式请求,如下所示:

  request = require 'superagent'
  user = request.agent()
  async.waterfall [
    (cb)->
      user.post('http://localhost:3000/form').send(name: 'Bob').end(cb)
  ], (err, res)->
    console.log err
    console.log res

这会成功打印完整的http响应,errundefined

如果我通过额外的步骤执行完全相同的操作:

  request = require 'superagent'
  user = request.agent()
  async.waterfall [
    (cb)->
      user.post('http://localhost:3000/form').send(name: 'Bob').end(cb)
    (err, res)->
      # this is never reached
      cb()
  ], (err, res)->
    console.log err # this now prints out the response
    console.log res # this is undefined

err现在是回复。 res未定义。这是我遇到的superagent问题,还是我只是错误地使用async waterfall

2 个答案:

答案 0 :(得分:1)

异步瀑布直接将错误传递给它的回调。数组中的第二个函数只接收一个参数 - res。并且数组中的每个函数都应该将它自己的回调作为最后一个参数。如果发生错误,你应该参与瀑布的回调。尝试:

async.waterfall([
  function(cb){
    superagent...end(cb);
  },
  function(res, cb){ //Note cb here.
    //If you don't pass res here, waterfall's callback will not receive it
    cb(null, res); 
  }], function(err, res){
    //If superagent fails you should catch err here
    should.not.exist(err);
    //res is defined because you passed it to callback of the second function
    should.exist(res); 
 });

答案 1 :(得分:1)

他们选择如何处理作为回调传递的函数,这是一个SuperAgent“问题”。如果该函数正好期待length property报告的两个参数,那么“传统”errres就像Async所希望的那样。如果您传递的函数未将其长度报告为2,则给出的第一个参数为res。这是SuperAgent's source for handling callbacks

Request.prototype.callback = function(err, res){
  var fn = this._callback;
  if (2 == fn.length) return fn(err, res);
  if (err) return this.emit('error', err);
  fn(res);
};

为了保证您的回调按预期调用,我建议将匿名函数传递给end,这样它肯定会将其长度报告为两个,这样您就可以将任何错误传递给回调。

request = require 'superagent'
user = request.agent()
async.waterfall [
  (cb) ->
    user.post('http://localhost:3000/form').send(name: 'Bob').end (err, res) ->
      cb err, res
  (err, res) ->
    # err should be undefined if the request is successful
    # res should be the response
    cb null, res
], (err, res) ->
  console.log err # this should now be null
  console.log res # this should now be the response