【问题标题】:Can't get return value from async waterfall in node module无法从节点模块中的异步瀑布获取返回值
【发布时间】:2016-03-03 09:20:58
【问题描述】:

我制作了一个节点模块,它使用异步瀑布执行一些操作。它独立工作,并在通过 AJAX 调用运行时完成所有任务,但是,我的 AJAX 回调永远不会得到它的返回值。

//node module 

var boilerplateFn = function(params){
    async.waterfall([
        function(callback){
            //do task 1
            callback(null, results);
        },
        function(results, callback){
            //task 2 is write
            fs.writeFile(path, results, function(err){
                if (err){
                    console.log(err);
                }else{
                    callback(null, results)
                }
            })
        }
    ], function(err, results){
        return results
    });
}

module.exports = exports = boilerplateFn;

这会正确写入文件,如果我在最终函数中执行 console.log,我可以看到我的结果字符串。

但是,当我尝试将它包含在这样的路线中时:

var components = require('./app/js/node_components');
app.get('/process/:scale/:type', function(req, res){
    var data = processRequest(req.params);
    res.json(data);
});

function processRequest(params){
    console.log(componentents.boilerplateFn(params)) //prints undefined in Terminal
    return {
        result: componentents.boilerplateFn(params);
    }
}

我通过 jQuery AJAX 请求调用路由,文件写得很好,但是,我没有看到控制台中打印的返回数据,就像我期望的那样:

return $.ajax({
        type: 'get',
        url: 'http://localhost:8888/' + paramStr,
        dataType: 'json'
    }).done(function(data){
        console.log('returned data', data) //returned data Object{}
    }).fail(function(jqObj, textStatus, err){
        console.log(jqObj, textStatus, err);
    })
});

我假设这意味着我的文件正在写入,但我的函数已经返回,所以它永远不会得到返回的文本。但是,我尝试将 res.json 包装在回调中,但它没有改变任何东西。

    processRequest(req.params, function(data){
      res.json(data);
    });


function processRequest(params, callback){
    var data = componentents.boilerplateFn(params);
    callback(data);
}

并不奇怪它不起作用,只是一个想法。如何将返回值返回给调用模块的函数?还是我刚刚做了一些根本不正确的事情?

【问题讨论】:

    标签: javascript node.js asynchronous express promise


    【解决方案1】:

    你不能把异步的东西当作同步的。相反,传入一个回调:

    var boilerplateFn = function(params, cb) {
      async.waterfall([
        function(callback) {
          // do task 1
          callback(null, results);
        },
        function(results, callback) {
          // task 2 is write
          fs.writeFile(path, results, function(err) {
            if (err) {
              callback(err);
            } else {
              callback(null, results);
            }
          })
        }
      ], cb);
    }
    
    module.exports = boilerplateFn;
    

    然后像这样使用它:

    var components = require('./app/js/node_components');
    app.get('/process/:scale/:type', function(req, res) {
      processRequest(req.params, function(err, data) {
        // TODO: check `err` first
        res.json({ result: data });
      });
    });
    
    function processRequest(params, cb) {
      components.boilerplateFn(params, cb);
    }
    

    【讨论】:

    • 谢谢,效果很好。在这个回调cessRequest(req.params, function(err, data) {中,参数errdata是从哪里来的。当 async 在最后一行被 ], cb); 引用,没有 (err, data) 或其他任何东西时,它如何知道将它们传递给这个函数。
    • 这些参数来自async.waterfall() 的“最终”回调(在所有“瀑布”函数完成后调用的回调),它将这两个值传入。
    【解决方案2】:

    你又在做同样的事情:

    function processRequest(params, callback){
        var data = componentents.boilerplateFn(params); //this writes undefined to data 
        callback(data);
    }
    

    最简单的办法就是直接在.get请求中调用函数,不要过度设计

    var components = require('./app/js/node_components');
    app.get('/process/:scale/:type', function(req, res){
        componentents.boilerplateFn(req.params, function(err, results){
            if (err){
               //handle error
            }else{
                res.json(data);
            }
        });
    });
    
    
    
    var boilerplateFn = function(params, cb){
    async.waterfall([
        function(callback){
            //do task 1
            callback(null, results);
        },
        function(results, callback){
            //task 2 is write
            fs.writeFile(path, results, function(err){
                if (err){
                    console.log(err);
                }else{
                    callback(null, results)
                }
            })
        }
    ], cb);
    }
    
    module.exports = exports = boilerplateFn;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多