用异步系列重写回调函数

时间:2013-11-28 06:16:26

标签: node.js express

我有这个功能:

exports.profileImage = function(req, res) {
    var id = req.params.user_id;
    userProvider.get(id, function(err, user){
        if (err) throw err;
        userProvider.getImageById(user['image_id'], function(err, image) {
            if (err) throw err;
            userProvider.writeImageToDisk(image, function(err, path){
                if (err) throw err;
                res.sendfile(path);
            });
        });
    });
};

我使用局部变量重写它:

exports.profileImage = function(req, res) {
var id = req.params.user_id;
var userTemp = undefined;
var imageTemp = undefined;
async.series([
    userProvider.get(id, function(err, user){
        if (err) throw err;
        userTemp = user;
    }),
    userProvider.getImageById(userTemp['image_id'], function(err, image) {
        if (err) throw err;
        imageTemp = image;
    }),
    userProvider.writeImageToDisk(imageTemp, function(err, path){
        if (err) throw err;
        res.sendfile(path);
    })
]);}

我有一个userProvider.getImageById(用户json对象)需要的参数,它来自userProvider.get函数,之前调用过,我把它保存到局部变量。

我选择异步来跳过回调地狱,但它无效。

错误:

Cannot read property 'image_id' of undefined.

3 个答案:

答案 0 :(得分:1)

在您尝试查找其userTemp时,

undefinedimage_id。只有在调用前一个异步函数时,它才会变为未定义。

答案 1 :(得分:1)

使用async.waterfall,您应该可以将代码大大简化为(未经测试的);

var id = req.params.user_id;
async.waterfall([
    function(callback) {
       userProvider.get(id, callback);
    },
    function(user, callback) {
       userProvider.getImageById(user['image_id'], callback);
    },
    userProvider.writeImageToDisk,
    res.sendfile
]);

答案 2 :(得分:0)

这不是async.series的工作方式。

数组中的每个函数都必须具有以下签名:

function(callback) { ...; callback(...); };

完成每个函数的代码后,您需要调用回调函数以向async发出信号,指示它应该运行下一步(docs)。

所以你的代码应该是这样的:

async.series([
  function(callback) {
    userProvider.get(id, function(err, user) {
      if (err) throw err;
      userTemp = user;
      callback();
    });
  },
  function(callback) {
    userProvider.getImageById(userTemp['image_id'], function(err, image) {
      if (err) throw err;
      imageTemp = image;
      callback();
    });
  },
  function(callback) {
    userProvider.writeImageToDisk(imageTemp, function(err, path){
      if (err) throw err;
      res.sendfile(path);
      callback();
    });
  }
]);

更好的是,请查看async.waterfall以获取将结果从一个异步函数传递到下一个异步函数的方法。