nodejs之async 模塊

前言

針對JS的異步機制,JS社區給出了很多不同的解決方案,Async庫便是其中一種,可能也是對於控制異步操作最全面的資源。因爲該庫提供了70個函數,幾乎想所有的運用場景都考慮在內。

parallel

函數是平行執行

'use strict';

var async = require('async');

var some = 'hello';

//watchfall 最後一個參數是回調,前面的是參數

var first = function (cb) {
  console.log('i am first!');
  some = some + ' www ';
  //cb(new Error('i am error'), 10);
  cb(null, 10);
};

var second = function (cb, data) {
  console.log('i am second,data:', data);
  some = some + ' world';
  cb(null, 1000);
};

var end = function (err, data, data1) {
  console.log('end err:', err);
  console.log('end data:', data);
  console.log('end data1:', data1);
}


async.parallel([first, second], end);

/*
async.parallel({ first, second }, end);
*/

console.log('end.....', some);

在這裏插入圖片描述

series

函數順序執行

'use strict';

var async = require('async');

var some = 'hello';

//watchfall 最後一個參數是回調,前面的是參數

var first = function (cb) {
  console.log('i am first!');
  some = some + ' www ';
  //cb(new Error('i am error'), 10);
  cb(null, 10);
};

var second = function (cb, data) {
  console.log('i am second,data:', data);
  some = some + ' world';
  cb(null, 1000);
};

var end = function (err, data, data1) {
  console.log('end err:', err);
  console.log('end data:', data);
  console.log('end data1:', data1);
}


async.series([first, second], end);

console.log('-----------------------------------------');
console.log('-----------------------------------------');

async.series({ first, second }, end);


console.log('end.....', some);


在這裏插入圖片描述

watchfall

waterfall(tasks, [callback]) 

(多個函數依次執行,且前一個的輸出爲後一個的輸入)按順序依次執行多個函數。每一個函數產生的值,都將傳給下一個函數。如果中途出錯,後面的函數將不會被執行。錯誤信息以及之前產生的結果,將傳給waterfall最終的callback。

對於學過了js回調機制的小夥伴,waterfall是比較容易理解的,個人的理解就是,waterfall中傳入的函數數組tasks中,後一個函數爲前一個函數的回調,使用cb(null,args),這樣的形式調用下一個函數,如果出現異常,則直接使用cb(new Error(“錯誤的信息”))這樣的方式來捕捉異常,並調用最終的回調函數來處理,在這種情況下,出現異常的函數後面那些函數,將不再繼續執行,測試代碼如下:

var async = require('async');
var a = 10;
async.waterfall([
    function(cb) {
        console.log("getb")
        setTimeout(function() {
            if (a == 0) {
                cb(new Error("a不能爲0"));
            } else {
                var b = 1 / a;
                cb(null, b); //在這裏通過回調函數把b傳給下一個函數,記得一定要加上null,才能調用數組中得下一個函數,否則,會直接調用最終的回調函數,然後結束函數,則後面的函數將不再執行
                //如果這裏寫成cb(b);
                //結果會變成:
                /**
                 *getb
                 *0.1
                 **/
            }
        }, 1000);
    },
    function(b, cb) {
        setTimeout(function() {
            console.log("getc")
            var c = b + 1;
            cb(null,c);
        }, 1000);
    }
], function(err, result) {
    if (err) {
        console.log(err);
    } else {
        console.log('c:' + result)
    }
});

當a = 0時,會直接拋出錯誤,輸出如下:

getb
Error: a不能爲0

先執行了第一個函數,在第一個函數中拋出異常之後,直接執行最終的回調函數,並沒有接着執行第二個函數。
a = 10 時,輸出如下:

getb
getc
1.1

先執行了第一個函數,然後把第一個函數算出的b傳給了第二個函數,再次算出第二個函數中得C,傳給最終的結果result。

https://github.com/caolan/async/blob/v1.5.2/README.md#waterfall

map,mapLimit

map(coll, iteratee, callbackopt)
mapLimit(coll, limit, iteratee, callbackopt)

whilst(test, iteratee, callbackopt)

Repeatedly call iteratee, while test returns true. Calls callback when stopped, or an error occurs.

var count = 0;
async.whilst(
    function test(cb) { cb(null, count < 5); },
    function iter(callback) {
        count++;
        setTimeout(function() {
            callback(null, count);
        }, 1000);
    },
    function (err, n) {
        // 5 seconds have passed, n = 5
    }
);

之前關於test部分的寫法是:
function () { return count < 5; }, 這樣寫,導致後面iter函數並不會執行,直接跳過這個函數。在這個函數栽過跟頭。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章