2015-11-29 23 views
0

我有一個節點模塊,我使用異步瀑布執行一些操作。它獨立工作,並在通過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); 
} 

不是真的感到驚訝它沒有工作,只是一個想法。我怎樣才能讓我的返回值返回到調用模塊的函數?或者我只是做了一些根本不正確的事情?

回答

3

你不能把異步的東西看作是同步的東西。相反,通過在回調:

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

謝謝,這很好。在這個回調'cessRequest(req.params,function(err,data){',參數'err'和'data'來自哪裏)。async知道如何將它們傳遞給這個函數。最後一行用'],cb);',no(錯誤,數據)'或任何東西。 – 1252748

+0

這些參數來自「final」回調(在所有「waterfalled」函數完成後調用的那個回調函數),其中的'async.waterfall()'將這兩個值傳入。 – mscdex

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;