使用async實現非同步控制

Jakeeee發表於2019-03-02

async官方DOC

介紹

node安裝

npm install async --save複製程式碼

使用

var async = require(`async`)複製程式碼

js檔案

github.com/caolan/asyn…

async提供了很多函式用於非同步流程控制,下面是async核心的幾個函式,完整的函式請看async官方DOC

    async.map([`file1`,`file2`,`file3`], fs.stat, function(err, results) {
    // results is now an array of stats for each file
    });

    async.filter([`file1`,`file2`,`file3`], function(filePath, callback) {
      fs.access(filePath, function(err) {
        callback(null, !err)
      });
    }, function(err, results) {
        // results now equals an array of the existing files
    });

    async.parallel([
        function(callback) { ... },
        function(callback) { ... }
    ], function(err, results) {
        // optional callback
    });

    async.series([
        function(callback) { ... },
        function(callback) { ... }
    ]);複製程式碼

series序列

series的作用就是按照順序一次執行。

async.series([
  function(callback) {
    setTimeout(function() {
      callback(null, 1)
        }, 2000);
    },
  function(callback) {
    callback(null, 2);
  }],
  function(err, results) {
    console.log(results);
  });複製程式碼

輸出結果為

[ 1, 2 ]複製程式碼

series函式的第一個引數可以是一個陣列也可以是一個JSON物件,引數型別不同,影響的是返回資料的格式。

async.series({
    one: function(callback){
        callback(null, 1);
    },
    two: function(callback){
        callback(null, 2);
    }
},function(err, results) {
    console.log(results);
});複製程式碼

輸出為

{one: 1, two: 2}複製程式碼

waterfall瀑布流

waterfallseries函式都是按照順序執行,不同之處是waterfall每個函式產生的值都可以傳遞給下一個函式,series不可以。

async.waterfall([
    function(callback) {
        callback(null, `one`, `two`);
    },
    function(arg1, arg2, callback) {
        // arg1 now equals `one` and arg2 now equals `two`
        console.log(`function 2`)
        console.log(`arg1: ` + arg1)
        console.log(`arg2: ` + arg2)
        callback(null, `three`);
    },
    function(arg1, callback) {
        console.log(`function 3`)
        console.log(`arg1: ` + arg1)
            // arg1 now equals `three`
        callback(null, `done`);
    }
], function(err, result) {
    // result now equals `done`
    console.log(result);
});複製程式碼

輸出

function 2
arg1: one
arg2: two
function 3
arg1: three
done複製程式碼

waterfall第一個引數只能為陣列。當中途有函式出錯,其err直接傳給最終callback,結果被丟棄,後面的函式不再執行。

parallel(tasks, [callback])

paraller函式是並行執行多個函式,每個函式都是立即執行,不需要等待其它函式先執行。
傳給最終callback的陣列中的資料按照tasks中宣告的順序,而不是執行完成的順序。

async.parallel([
    function(callback){
        callback(null, `one`);
    },
    function(callback){
        callback(null, `two`);
    }
],
function(err, results){

});複製程式碼

tasks引數可以是一個陣列或是json物件,和series函式一樣,tasks引數型別不同,返回的results格式會不一樣。

將示例中tasks的回撥函式用setTimeout在1000毫秒後呼叫,然後在parallel的回撥函式中輸出results,看一看整個過程花費了1s還是2s。

var async=require("async");
async.parallel([
    function(callback){
        setTimeout(function(){
            callback(null, `one`)
        },1000);
    },
    function(callback){
        setTimeout(function(){
            callback(null, `two`)
        },1000);
    }
],
function(err, results){
    console.log(results);
});複製程式碼

parallelLimit(tasks, limit, [callback])

parallelLimit函式和parallel類似,但是它多了一個引數limit。 limit引數限制任務只能同時併發一定數量,而不是無限制併發,示例如下:

async.parallelLimit([
    function(callback){
        callback(null, `one`);
    },
    function(callback){
        callback(null, `two`);
    }
],
2,
function(err, results){

});複製程式碼

將示例中tasks的回撥函式用setTimeout在1000毫秒後呼叫,limit引數設定為1,然後在parallelLimit的回撥函式中輸出results,看一看整個過程花費了1s還是2s。

var async=require("async");
async.parallelLimit([
    function(callback){
        setTimeout(function(){
            callback(null, `one`);
        }, 1000);
    },
    function(callback){
        setTimeout(function(){
            callback(null, `two`);
        }, 1000);
    }
],
1,
function(err, results){
    console.log(results);
});複製程式碼

map(coll, iteratee, callbackopt)

map函式遍歷傳入的陣列,並執行同樣的操作,最終返回結果

  • cool:陣列
  • iteratee:對陣列每一項要執行的函式
  • callbackopt:回撥函式
async.map([1, 2, 3, 4, 5],
    function(item, callback) {
        callback(null, item + 5)
    },
    function(err, result) {
        console.log(result)
    })複製程式碼
[ 6, 7, 8, 9, 10 ]複製程式碼

相關文章