我有一个节点模块,它使用异步瀑布执行一些操作。它独立运行,并在通过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);
}
并不感到惊讶它不起作用,只是一个想法。如何将返回的值恢复为调用模块的函数?或者我刚刚做了一些根本不正确的事情?
答案 0 :(得分:4)
您不能将异步的内容视为同步内容。而是传递一个回调:
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);
}
答案 1 :(得分:0)
你在这里又做了同样的事情:
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;