async 非同步流程控制
async
是一個強大的非同步流程控制庫,其語義類似於js
對陣列的操作。它提供了一系列非常強大而便捷的方法,有助於我們在javascript
單執行緒模型背景下寫出優雅的邏輯控制程式碼。
牛刀小試
先從檔案操作開始初步瞭解async
函式庫的作用:
- 使用
filter
過濾出磁碟中存在的檔案
const fs = require('fs');
const async = require('async');
async.filter(['f1', 'f2', 'f3'], function(it, callback) {
fs.access(it, function (err) {
callback(null, !err);
});
}, function(err, results) {
console.log(results);
});
假設當前目錄下存在以上三個檔案,那麼results
輸出為:
['f1', 'f2', 'f3']
- 使用
map
判斷檔案是否存在
async.map(['f1', 'f2', 'f3'], function(it, callback) {
fs.exists(function(exists) {
callback(null, exists);
});
}, function (err, results) {
console.log(results);//[true, true, true]
});
以上兩個例子分別使用了
access
與exists
判斷檔案是否存在,關於兩個API
的詳細說明,請檢視nodejs
官方文件
- 常用的多工並行
function asyncTask(delay, arg) {
return function(callback) {
setTimeout(function() {
console.log(arg + "done");
callback(null , arg);
}, delay);
};
}
async.parallel([
asyncTask(10, "task1"),
asyncTask(1, "task2"),
asyncTask(100, "task3"),
], function(err, ret) {
console.log(ret);
});
asyncTask
輸出的順序依次為:
[[email protected] async]$ node app.js
task2done
task1done
task3done
//ret
[ 'task1', 'task2', 'task3' ]
可見雖然任務是並行的,但是最終的結果依然按照任務陣列的順序排列。
- 順序執行任務
function asyncTask(delay, arg) {
return function(callback) {
setTimeout(function() {
console.log(arg + "done");
callback(null, arg);
}, delay);
};
}
async.series([
asyncTask(10, "task1"),
asyncTask(1, "task2"),
asyncTask(100, "task3"),
], function(err, ret) {
console.log(ret);
});
輸出:
[[email protected] async]$ node app.js
task1done
task2done
task3done
[ 'task1', 'task2', 'task3' ]
可以看到任務按照傳入的順序依次執行。
集合型別多工處理
each
each
函式依次遍歷陣列執行回撥函式:
function readFile(file, callback) {
fs.readFile(file, function(err, ret) {
console.log("readFile "+ file + " done");
callback(err);
});
}
async.each(['f1', 'f2', 'f3'], readFile, function(err) {
console.log("all done");
});
需要注意的是,each不能保證迭代函式完成的順序,這取決於使用者的具體任務
forEachOf
each
函式可以對陣列進行遍歷,如果想要遍歷的是一個物件,那麼需要用到forEachOf
.
function readFile(file, k, callback) {
fs.readFile(file, function(err, ret) {
console.log("readFile "+ k + " " + file + " done");
callback(err);
});
}
async.forEachOf({k1: "f1", k2: "f2", k3: "f3"}, readFile, function(err) {
console.log("all done");
});
迭代函式第一個引數是value
,第二個引數是key
.
- 控制
each
和foEachOf
的順序
eachSeries
與forEachOf
都是用來控制迭代函式的順序執行:
function readFile(file, k, callback) {
fs.readFile(file, function(err, ret) {
console.log("readFile "+ k + " " + file + " done");
callback(err);
});
}
async.forEachOfSeries({k1: "f1", k2: "f2", k3: "f3"}, readFile, function(err) {
console.log("all done");
});
這樣程式的輸出始終是:
[[email protected] async]$ node app.js
readFile k1 f1 done
readFile k2 f2 done
readFile k3 f3 done
all done
- 使用
apply
包裝非同步任務
前面幾個非同步任務都需要人為的額外寫一個函式,如asyncTask
,async
提供一個apply
語法糖用於解決此類問題:
// 使用 apply
async.parallel([
async.apply(fs.writeFile, 'testfile1', 'test1'),
async.apply(fs.writeFile, 'testfile2', 'test2'),
]);
// 等同於
async.parallel([
function(callback){
fs.writeFile('testfile1', 'test1', callback);
},
function(callback){
fs.writeFile('testfile2', 'test2', callback);
}
]);
- 使用
Limit
類函式控制併發數量
async
為每個介面都提供了一個Limit
引數,使用者限制併發數量,我們利用filterLimit
做一個簡單的測試:
var count = 0;
async.filterLimit([1, 10, 28, 90, 10], 2, function(it, callback) {
count++;
console.log(it + "開始");
console.log("併發數:", count);
setTimeout(function() {
count--;
console.log(it + "結束");
callback(null);
}, it);
}, function(results) {
console.log(results);
});
輸出:
[[email protected] async]$ node app.js
1開始
併發數: 1
10開始
併發數: 2
1結束
28開始
併發數: 2
10結束
90開始
併發數: 2
28結束
10開始
併發數: 2
10結束
90結束
null
可以看到,最大併發數也就是2
,雖然待執行任務大於2
.
async
幾乎提供了全類陣列操作型別的介面,例如:sortBy
、reduce
、some
等,這裡不再一一展開。
非同步控制函式
前面介紹了兩個非同步流程控制函式:series
和parallel
。下面介紹其他幾個流程控制函式:
- 使用
whilst
實現while
操作
whilst
用於實現,類似於while
的效果,直到滿足條件,否則持續執行回撥函式。
var c = 0;
async.whilst(function() {
console.log("judge");
return c < 3;
}, function(callback) {
c++;
console.log("try " + c);
setTimeout(function() {
callback(null, c);
}, 1000);
}, function(err, val) {
console.log('err', err);
console.log('value: ', val);
});
輸出:
[[email protected] async]$ node app.js
judge
try 1
judge
try 2
judge
try 3
judge
err null
value: 3
- 使用
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'
});
相關推薦
async 非同步流程控制
async是一個強大的非同步流程控制庫,其語義類似於js對陣列的操作。它提供了一系列非常強大而便捷的方法,有助於我們在javascript單執行緒模型背景下寫出優雅的邏輯控制程式碼。 牛刀小試 先從檔案操作開始初步瞭解async函式庫的作用:
node.js對mongodb的連接&增刪改查(附async同步流程控制)
color var literal int lba node () n! node.js 1.啟動mongodb數據庫 官網下載mongodb數據庫 在mongodb根目錄下創建文件夾:假設取名為test。 我們認為test就是mongodb新建的數據庫一枚。 創建批處理文
JavaScript非同步流程控制全攻略
一.js非同步流程的由來 眾所周知,Javascript語言的執行環境是單執行緒(single thread),作為瀏覽器指令碼語言,JavaScript的主要用途是與使用者互動,以及操作DOM。若以多執行緒的方式操作這些DOM,則可能出現操作
Nodejs:非同步流程控制(下)
//非同步操作,序列有關聯(瀑布流模式) //npm install async --save-dev var async = require('async'); function exec() { async.waterfall( [ fun
Nodejs:非同步流程控制(上)
function oneFun() { // setTimeout(function () { // console.log("a"); // }, 1000); i = 0; setInterval(function () {
node.js對mongodb的連線&增刪改查(附async同步流程控制)
最近嘗試了node.js和mongodb的使用。下面來一波步驟。 1.啟動mongodb資料庫 官網下載mongodb資料庫 在mongodb根目錄下建立資料夾:假設取名為test。 我們認為test就是mongodb新建的資料庫一枚。 建立批處理
一道promise的小題目(Promise非同步流程控制)
用Promise控制非同步流程,三個非同步任務,時間可能有先後,但是要按照想要的順序輸出。 我這裡用四種方法解決,其實也就是考察你對Promise的理解,基礎題了。 //實現mergePromise函式,把傳進去的陣列順序先後執行, //並且把返回的資料先後放到陣列data中 const timeout =
Node非同步爬蟲引出的非同步流程控制的一些問題
前記: 想寫一個電影天堂的爬蟲,因為node很長時間落下,就想用node去寫一下。結果遇到了一些列的問題,這些問題歸根到底就是非同步流程控制的問題,在以前就一直會接觸到很多回調地獄,Promise為什麼會出現諸如此類的話題,現在終於是深刻體會到了! 開始的程式碼是: const cheerio = requi
Node.js系列--非同步流程控制
<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);"> </span><span style="font-
node js 非同步執行流程控制模組Async介紹
sync是一個流程控制工具包,提供了直接而強大的非同步功能。基於Javascript為Node.js設計,同時也可以直接在瀏覽器中使用。 Async提供了大約20個函式,包括常用的 map, reduce, filter, forEach 等,非同步流程控制模式包括,序列(series),並行(para
async異步流程控制
cno ace dea 方式 limit 中一 有關 參數 err http://cnodejs.org/topic/54acfbb5ce87bace2444cbfb 先安裝:G:\www\nodejs\one\models>npm install async --s
js非同步操作的流程控制——20181114
序列執行(程式碼可直接在console控制檯執行) var items = [ 1, 2, 3, 4, 5, 6 ]; var results = []; function async(arg, callback) { console.log('引數為 ' + arg +' , 1秒後返回
現代JS中的流程控制:詳解Callbacks 、Promises 、Async/Await
JavaScript經常聲稱是_非同步_。那是什麼意思?它如何影響發展?近年來這種方法有何變化? 請思考以下程式碼: result1 = doSomething1(); result2 = doSomething2(result1); 大多數語言都處理每一行同步。第一行執行並返回結果。第二行在第一行完
node的async流程控制包parallel的實現
Async介紹 Async是一個流程控制工具包,提供了直接而強大的非同步功能。基於Javascript為Node.js設計,同時也可以直接在瀏覽器中使用。 Async提供了大約20個函式,包括常用的map, reduce, filter, forEach 等,非同步流程
JS的四種非同步方式:回撥/監聽/流程控制庫/promise
你可能知道,Javascript語言的執行環境是”單執行緒”(single thread)。 所謂”單執行緒”,就是指一次只能完成一件任務。如果有多個任務,就必須排隊,前面一個任務完成,再執行後面一個任務,以此類推。 這種模式的好處是實現起來比較簡單,執行環
Async詳解之一:流程控制
為了適應非同步程式設計,減少回撥的巢狀,我嘗試了很多庫。最終覺得還是async最靠譜。 Async的內容分為三部分: 流程控制:簡化十種常見流程的處理 集合處理:如何使用非同步操作處理集合中的資料 工具類:幾個常用的工具類 本文介紹其中最簡單最常用的流程控制部分。
C#基礎知識-流程控制的應用(四)
相關 ats 循環 nbsp 使用 logs 嘗試 exc 設置斷點 流程控制我們在編程中運用到的地方非常的多,在上篇中僅僅只是簡單的介紹每一種的使用,並沒有運用到實例中,很難去理解它真正的作用。下面我們將實際的運用流程控制的代碼寫一些實例相關的程序,加深對流程控制的理解,
js---11運算符,流程控制,真假
arr body color 空格 one round red 轉換 class <!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content="tex
JS3流程控制
代碼塊 語句 write 次循環 var break tex document if...else 比較簡單(與java中的流程控制一樣) 做判斷(if語句) if(條件){ 條件成立時執行代碼} 二選一 (if...else語句) if(條件){ 條件成立時執行的代碼}e
Shell腳本的基本流程控制
false 流程控制 ash lba -s print 所有 循環 數字 if else read -p ‘請輸入分數:‘ score if [ $score -lt 60 ]; then echo ‘60分以下‘ elif [ $score -lt 70 ]; th