2016-10-26 142 views
1

我正在嘗試在節點js中使用異步來控制某些函數的執行流。在下面的代碼中,我有三個聲明的函數,應該分別打印'one','two'和'3',並執行其他任務(打印只是爲了讓我看到什麼時候執行)。異步 - 回調不是函數

async.waterfall([ 
    function(callback) { 
     settings(); 
     console.log("1"); 
     callback(null, 'one'); 
    }, 
    function(callback) { 
     profile(); 
     console.log("2"); 
     callback(null, 'two'); 
    }, 
    function(callback) { 
     console.log("3"); 
     groups(); 
     callback(null, 'two'); 
    } 
    ]); 

所以我得到的錯誤「回調不是一個函數」在回調線(NULL,「兩節」); 說實話,這可能是一個非常虛擬的問題,我不完全理解異步瀑布是如何工作的。但是我認真地嘗試了一下,通過閱讀例子,試圖實現短代碼並試着玩弄它。

有趣的是,如果使用async.series代替async.waterfall,則不會出現此類錯誤。但是,async.series將打印1,2,3,三,一,二。 瀑布模型中的數字按順序打印,但裏面的函數不按正確的順序執行。

要注意的是,前兩個函數 - 設置和配置文件 - 包括數據庫讀取和計算,而第三個函數只打印一些結果。

+0

的珍貴版本,特別是如果你調用'async.series'的'async.waterfall',反之亦然,'async'內部出現此問題,當你窩'async'電話,將變得不可靠。 – Sandwich

回答

2

隨着async.waterfall,結果被傳遞到下一個功能作爲參數。例如:

async.waterfall([ 
    function(callback) { 
     callback(null, 'one', 'two'); 
    }, 
    function(arg1, arg2, callback) { 
     // arg1 now equals 'one' and arg2 now equals 'two' 
     callback(null, 'three'); 
    }, 
    function(arg1, callback) { 
     // arg1 now equals 'three' 
     callback(null, 'done'); 
    } 
], function (err, result) { 
    // result now equals 'done' 
}); 

在你的情況,callback第二功能將收到的字符串one作爲參數。因此,你正在經歷的錯誤。

3

爲了簡化起見,callback(null, 'one')表示您將一個參數傳遞給next。含義你的功能需要在回調前接受1個參數。

callback(null, 'one')遵循function(arg1, callback)其中arg1 = 'one'

callback(null, 'one', 'two')遵循function(arg1, arg2, callback)其中arg1='one'arg2='two'

async.waterfall([ 
    function(callback) { 
     settings(); 
     console.log("1"); 
     callback(null, 'one'); 
    }, 
    function(arg1, callback) { 
     profile(); 
     console.log("2"); 
     callback(null, 'two'); 
    }, 
    function(arg1, callback) { 
     console.log("3"); 
     groups(); 
     callback(null, 'two'); 
    } 
    ]); 
1

這是不使用waterfall試圖通過在其他功能參數和回調把最後一個參數正確的方式。

async.waterfall([ 
function(callback) { 
    settings(); 
    console.log("1"); 
    callback(null, 'one'); 
}, 
function(previous_value,callback) { 
    profile(); 
    console.log("2"); 
    callback(null, 'two'); 
}, 
function(previous_value,callback) { 
    console.log("3"); 
    groups(); 
    callback(null, 'two'); 
} 
], function(err,result){console.log(result)}); 

你也忘記了所有的執行後通過最終回調。

2

瀑布

所有我建議你使用異步自動到位瀑布模型背後的原因是在瀑布模型首先我們將通過一個移動一個像第一,我們將完成第一個函數的執行,然後繼續前進到第二和第三。Ë我們將在一系列不事項經得起我們的功能都依賴於這種相互與否

自動

汽車的好處是,它並沒有真正重要的天氣你的功能都依賴於對方爲汽車能運行一系列任務(對於相關的函數)和平行(爲其不依賴於彼此的功能)

async.auto({ 
    get_data: function(callback) { 
     console.log('in get_data'); 

     callback(null); 
    }, 
    make_folder: function(callback) { 

     callback(null); 
    }, 
    write_file: ['get_data', 'make_folder', function(results, callback) { 

     callback(null); 
    }], 
    email_link: ['write_file', function(results, callback) { 

     callback(null); 
    }] 
}, function(err, results) { 

}); 

這裏在上面的例子中,我們有GET_DATA功能和make_folder函數不依賴於彼此,所以我們可以並行運行並通過傳遞名稱get_Data & ma ke_folder我們可以限制write_file函數只有在執行上面的兩個函數之後才能運行。

瞭解更多詳情,您可以訪問http://caolan.github.io/async/docs.html#auto

甚至一看就async.autoInject它最近被添加的,地方汽車的非同步的。但汽車將繼續爲異步

+0

雖然我有一個問題。下一個函數是否等待前一個函數完成執行?或者我必須自己處理這個問題? –

+0

肯定它確實@Freya像例子中,我已經給我們有一個WRITE_FILE功能,將等待「GET_DATA」,「make_folder」當他們兩人得到執行,然後只將WRITE_FILE得到執行第一次完整。 –

+0

我發現答案很有幫助,謝謝。因此,upvote。但這不是唯一有用的答案,實際上並沒有針對具體的問題。來這裏遇到類似問題的人想知道回調是如何工作的,而不是在不同場景中使用的異步類型,或者.waterfall和.auto之間的區別。 –