在學(xué)習(xí) Node.js 過程中接觸到了如何使用 async 來控制并發(fā)(使用 async 控制并發(fā))
async 的本質(zhì)是一個流程控制。其實在異步編程中,還有一個更為經(jīng)典的模型,叫做 Promise/Deferred 模型(當(dāng)然還有更多相關(guān)解決方法,比如 eventproxy,co 等,到時候遇到在挖坑)
首先,我們思考一個典型的異步編程模型,考慮這樣一個題目:讀取一個文件,在控制臺輸出這個文件內(nèi)容
var fs = require('fs');fs.readFile('1.txt', 'utf8', function (err, data) { console.log(data);});看起來很簡單,再進(jìn)一步: 讀取兩個文件,在控制臺輸出這兩個文件內(nèi)容
var fs = require('fs');fs.readFile('1.txt', 'utf8', function (err, data) { console.log(data); fs.readFile('2.txt', 'utf8', function (err, data) { console.log(data); });});要是讀取更多的文件呢
var fs = require('fs');fs.readFile('1.txt', 'utf8', function (err, data) { fs.readFile('2.txt', 'utf8', function (err, data) { fs.readFile('3.txt', 'utf8', function (err, data) { fs.readFile('4.txt', 'utf8', function (err, data) { // ... }); }); });});這就是傳說中的 callback hell,可以使用 async 來改善這段代碼,但是在本例中我們要用 promise/defer 來改善它
promise 基本概念
首先它是一個對象,它和 javascript 普通的對象沒什么區(qū)別,同時,它也是一種規(guī)范,跟異步操作約定了統(tǒng)一的接口,表示一個異步操作的最終結(jié)果,以同步的方式來寫代碼,執(zhí)行的操作是異步的,但又保證程序執(zhí)行的順序是同步的
1. promise 只有三種狀態(tài),未完成,完成 (fulfilled) 和失敗 (rejected)
2. promise 的狀態(tài)可以由未完成轉(zhuǎn)換成完成,或者未完成轉(zhuǎn)換成失敗
3. promise 的狀態(tài)轉(zhuǎn)換只發(fā)生一次
promise 有一個 then 方法,then 方法可以接受 3 個函數(shù)作為參數(shù)。前兩個函數(shù)對應(yīng) promise 的兩種狀態(tài) fulfilled, rejected 的回調(diào)函數(shù)。第三個函數(shù)用于處理進(jìn)度信息
為了理解它,一些重要原理必須記牢:.then() 總是返回一個新的 promise,如下面代碼:
var promise = readFile()var promise2 = promise.then(readAnotherFile, console.error)
這里 then 的參數(shù) readAnotherFile, console.error 是代表異步操作成功后的動作 onFulfilled 或失敗后的動作 OnRejected,也就是說,讀取文件成功后執(zhí)行 readAnotherFile 函數(shù),否則失敗打印記錄錯誤。這種實現(xiàn)是兩個中只有一種可能
也可以理解為:
promiseSomething().then(function (fulfilled) { // 當(dāng) promise 狀態(tài)變成 fulfilled 時,調(diào)用此函數(shù)}, function (rejected) { // 當(dāng) promise 狀態(tài)變成 rejected 時,調(diào)用此函數(shù)}, function (progress) { // 當(dāng)返回進(jìn)度信息時,調(diào)用此函數(shù)});
新聞熱點
疑難解答
圖片精選