2016-05-17 90 views
1

我希望函數cb只能在函數f1和f2完成後調用(請注意,f1和f2是異步的,它們可能隨時調用) 。只有在執行了其他異步功能後才調用函數

我試圖實現這樣的東西,但它似乎不是在node.js上這樣做的最好方法。

var l1 = false; 
var l2 = false; 

// function to be called after f1 and f2 have ended 
function cb(err, res) { 
    if (err) { 
    console.log(err); 
    } else { 
    console.log('result = ' + res); 
    } 
} 

// f1 and f2 are practically identicals... 
function f1(callback) { 
    console.log('f1 called'); 
    l1 = true; 
    if (l2) { 
    console.log('f1 calling cb'); 
    callback(null, 'one'); 
    } else { 
    console.log('f2 wasn\'t called yet'); 
    } 
} 

function f2(callback) { 
    console.log('f2 called'); 
    l2 = true; 
    if (l1) { 
    console.log('f2 calling cb'); 
    callback(null, 'two'); 
    } else { 
    console.log('f1 wasn\'t called yet'); 
    } 
} 

setTimeout(function() { 
    f1(cb); // will call cb 
}, 3000); 
setTimeout(function() { 
    f2(cb); // won't call cb 
}, 1000); 

// It will print: 
// f2 called 
// f1 wasn't called yet 
// f1 called 
// f1 calling cb 
// result = one 
+2

使用承諾來實現這一點。 – Akhoy

+1

你願意使用外部庫嗎?對於像這樣的場景以及許多其他場景,名爲[異步](https://github.com/caolan/async)的應用程序是非常受歡迎的。如果你說你願意,我會寫一個答案,解釋如何將它應用到這個特定的場景。 –

+0

是的,的確,我一直在尋找一種使用外部庫的解決方案。我看着異步模塊,但找不到任何有用的東西。 – orangesky

回答

3
var async = require('async'); 

console.log('before invocation'); 

async.parallel([ 
    function f1(cb) { 
    console.log('f1 invoked'); 

    setTimeout(function() { 
     console.log('f1 calling back'); 
     cb(null, 'one'); 
    }, 3000); 
    }, 
    function f2(cb) { 
    console.log('f2 invoked'); 

    setTimeout(function() { 
     console.log('f2 calling back'); 
     cb(null, 'two'); 
    }, 1000); 
    } 
], function callback(err, results) { 
    console.log('callback invoked'); 

    if (err) { 
    console.log(err); 
    } else { 
    console.log('results: ', results); 
    } 
}); 

console.log('after invocation'); 

setTimeout(function() { 
    console.log('2 seconds later...'); 
}, 2000); 

輸出:

before invocation 
f1 invoked 
f2 invoked 
after invocation 
f2 calling back 
2 seconds later... 
f1 calling back 
callback invoked 
results: [ 'one', 'two' ] 

藉口的事實,我沒有複製您的方案完美,但我承認你有什麼大模型反正。

唯一的區別是最終回調包含來自並行執行的每個函數的結果數組,並且在每個函數中調用setTimeout()

請注意,返回的數組是['one', 'two'],因爲這是傳遞給async.parallel()的函數的順序。提供給每個函數的參數cb由async生成,它會自動爲您執行錯誤處理和其他後臺處理,類似於您如何使用兩個標記,但更有組織和有效。

+0

我看到這個解決方案的問題是當調用async.parallel()時,會調用f1和f2函數。實際上我沒有關於何時調用f1或f2的信息(它們是獨立的)。例如,現在可以調用f1,2分鐘後調用f2。 setTimeout只是一個例子,我應該像這樣: handler.on('some_event',f1); handler.on('other_event',f2); 感謝您的幫助! – orangesky

+0

@orangesky如果你可以詳細說明調用'f1'和'f2'是什麼以及這兩個函數應該做什麼(除了處理最終回調的標誌),我可以給你一個更好的答案。但是如果沒有這些信息,我很難確切地知道我在處理什麼。 –

相關問題