2014-02-17 122 views
0

我已經構建了一個NodeJS應用程序(使用Sails,但我認爲這是無關緊要的)。在等待響應時阻止函數

在我的行動中,我有一些要求加載其他服務,數據源等的請求。但是,由於對回調的巨大依賴性,在操作返回HTML之後,我的代碼仍然執行很長時間。我必須錯過一些愚蠢的東西(或不完全是異步的東西),但是我怎麼能阻止我的動作完成,直到我準備好所有的數據來呈現視圖?!

乾杯

回答

1

很難確切地說出問題所在,但這是一個猜測。假設你只有一個外部調用你的代碼應該是這樣的:

exports.myController = function(req, res) { 

    longExternalCallOne(someparams, function(result) { 

     // you must render your view inside the callback 
     res.render('someview', {data: result}); 
    }); 

    // do not render here as you don't have the result yet. 

} 

如果有兩個以上的外部調用你的代碼看起來是這樣的:

exports.myController = function(req, res) { 

    longExternalCallOne(someparams, function(result1) { 

     longExternalCallTwo(someparams, function(result2) { 

     // you must render your view inside the most inner callback 
     data = {some combination of result1 and result2}; 
     res.render('someview', {data: data }); 

     }); 

     // do not render here since you don't have result2 yet 

    }); 

    // do not render here either as you don't have neither result1 nor result2 yet. 

} 

正如你所看到的,一旦你有多個長時間運行的異步調用事情開始變得棘手。以上代碼僅用於說明目的。如果你的第二個回調取決於第一個,那麼你需要這樣的東西,但如果longExternalCallOne和longExternalTwo是相互獨立的,你應該使用像庫異步幫助並行請求https://github.com/caolan/async

+1

你通過讓我重新考慮情況來釘住它。謝謝! –

0

你不能阻止你的代碼。您只需檢查所有回調是否完成。如果是的話,繼續你的代碼。如果否,請等待下一個回調並再次檢查。

2

我建議你變得非常親近async library

的文檔是與上面的鏈接不錯,但它基本上可以歸結爲一堆非常方便的調用一樣的:

async.parallel([ 
    function(){ ... }, 
    function(){ ... } 
], callback); 

async.series([ 
    function(){ ... }, 
    function(){ ... } 
]); 

節點是固有異步,你需要學會去愛它。

0

您不應該停止您的代碼,而是在您的其他資源回調中呈現您的視圖,以便在呈現之前等待資源到達。這是node.js中的常見模式。

如果您必須等待多個回調被調用,那麼每次調用時都可以手動檢查,如果其他人也被調用(例如簡單的bool),如果是,則調用渲染函數。或者你可以使用異步或其他很酷的庫,這將使任務更容易。承諾(藍鳥圖書館)也是一個選擇。

0

我在這裏猜測,因爲沒有代碼示例,但您可能會運行到這樣的事情:

// let's say you have a function, you pass it an argument and callback 
function myFunction(arg, callback) { 
    // now you do something asynchronous with the argument 
    doSomethingAsyncWithArg(arg, function() { 
     // now you've got your arg formatted or whatever, render result 
     res.render('someView', {arg: arg}); 
     // now do the callback 
     callback(); 
     // but you also have stuff here! 
     doSomethingElse(); 

    }); 
}); 

所以,以後你渲染,你的代碼保持運行。如何預防它? return從那裏。

return callback(); 

現在你的內部函數將在它調用回調後停止處理。