最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Can't get return value from async waterfall in node module - Stack Overflow

programmeradmin2浏览0评论

I have a node module I made that performs some operations using async waterfall. It works standalone, and pletes all the tasks when run through an AJAX call, however, my AJAX callback never gets its return value.

//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;

This writes the file correctly, and if I do a console.log in the final function, I can see my results string.

However when I try to include it in a route like this:

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

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

and I make a call to the route through a jQuery AJAX request, the file is written fine, however, I don't see the returned data printed in the console like I'd expect:

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);
    })
});

I assume this means that my file is writing but that my function has already returned so it never gets the returned text. However, I tried wrapping res.json in a callback, but it didn't change anything.

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


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

Not really surprised it didn't work, just was an idea. How can I get my returned value back to the function that calls the module? Or have I just done something fundamentally incorrect?

I have a node module I made that performs some operations using async waterfall. It works standalone, and pletes all the tasks when run through an AJAX call, however, my AJAX callback never gets its return value.

//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;

This writes the file correctly, and if I do a console.log in the final function, I can see my results string.

However when I try to include it in a route like this:

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

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

and I make a call to the route through a jQuery AJAX request, the file is written fine, however, I don't see the returned data printed in the console like I'd expect:

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);
    })
});

I assume this means that my file is writing but that my function has already returned so it never gets the returned text. However, I tried wrapping res.json in a callback, but it didn't change anything.

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


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

Not really surprised it didn't work, just was an idea. How can I get my returned value back to the function that calls the module? Or have I just done something fundamentally incorrect?

Share Improve this question asked Nov 29, 2015 at 19:02 12527481252748 15.4k34 gold badges117 silver badges242 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 5

You can't treat something that is asynchronous as if it is synchronous. Instead, pass in a callback:

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;

Then use it like:

var ponents = require('./app/js/node_ponents');
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) {
  ponents.boilerplateFn(params, cb);
}

You are doing the same thing again here :

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

simplest solution is to call the function directly in the .get request, don't overdesign

var ponents = require('./app/js/node_ponents');
app.get('/process/:scale/:type', function(req, res){
    ponentents.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;
发布评论

评论列表(0)

  1. 暂无评论