路過的朋友,能夠點個贊,關注一下~~~
javascript
回調函數----->peomise------>generator + co----->async + awaitjava
回調函數能夠解決存在的異步問題,但回調函數分爲,同步與異步: node
callback git
回調函數自己是咱們約定俗成的一種叫法,咱們定義它,可是並不會本身去執行它,它最終被其餘人執行了。github
優勢
:比較容易理解;缺點
:1.高耦合,維護困難,回調地獄;2.每一個任務只能指定一個回調函數;3.若是幾個異步操>做之間並無順序之分,一樣也要等待上一個操做執行結束再進行下一個操做。npm
下圖回調地獄 編程
Promise
是異步編程的一種解決方案,比傳統的解決方案——回調函數和事件——更合理和更強大。promise
參考dom
理解:異步
Es6將promise歸入本身規範的時候,也遵循了一個相應的標準 — ``Promise A+規範。
將其概括爲4321規範
4:4大術語 3:3種狀態 2:2種事件 1:1個對象
解決(fulfill)
:指一個 promise 成功時進行的一系列操做,如狀態的改變、回調的執行。雖然規範中用 fulfill 來表示解決,但在後世的 promise 實現多以 resolve 來指代之。
拒絕(reject)
:指一個 promise 失敗時進行的一系列操做。
終值(eventual value)
:所謂終值,指的是 promise 被解決時傳遞給解決回調的值,因爲 promise 有一次性的特徵,所以當這個值被傳遞時,標誌着 promise 等待態的結束,故稱之終值,有時也直接簡稱爲值(value)。
據因(reason)
:也就是拒絕緣由,指在 promise 被拒絕時傳遞給拒絕回調的值。
針對每種狀態的規範
等待態(Pending) 處於等待態時,promise 需知足如下條件:
執行態(Fulfilled)
處於執行態時,promise 需知足如下條件:
拒絕態(Rejected)
處於拒絕態時,promise 需知足如下條件:
針對3種狀態,只有以下兩種轉換方向:
在狀態轉換的時候,就會觸發事件。
若是是
pending –> fulfiied
,就會觸發onFulFilled
事件 若是是pendeing –> rejected
,就會觸發onRejected
事件
就是指promise對象
let p = new Promise(function (resolve,reject) {
reject("no");
})
console.log('p :', p);
複製代碼
回調函數中的兩個參數,其做用就是用於轉換狀態:
resolve,將狀態從pending –> fullFilled reject,將狀態從pending –> rejected
在狀態轉換的時候,就會觸發事件
。
若是是pending –> fulfiied,就會觸發onFulFilled事件
若是是pendeing –> rejected,就會觸發onRejected事件
針對事件的註冊,Promise對象提供了then
方法,以下:
const fs = require("fs");
let p = new Promise(function (resolve,reject) {
fs.readFile("03-js基礎/a.txt","utf8",(err,date)=>{
if(err){
reject(err);
}else{
resolve(date);
}
});
});
p.then(result=>{
console.log('result :', result);
}).catch(err=>{
console.log('err :', err);
});
複製代碼
let p = new Promise((resolve,reject)=>{
setTimeout(()=>{
let num = Math.random();
if(num>0.5){
resolve("success");
}else{
reject("fail");
}
},1000);
});
p.then(result=>{
console.log('result :', result);
},err=>{
console.log('err :', err);
})
複製代碼
const fs = require("fs");
function readFile(file){
return new Promise((resolve,reject)=>{
fs.readFile("file","utf8",(err,date)=>{
if(err){
reject(err);
}else{
resolve(date);
}
});
});
}
readFile("a.txt").then(result=>{
console.log('result :', result);
},err=>{
console.log('err :', err);
})
複製代碼
all:全部,所有執行,而且知足要求 race:競賽,誰跑的快,執行誰的(不分紅功與失敗)
all和race都是Promise構造器對象的靜態方法。直接使用Promise調用,以下:
promise
對象。當有多個異步操做的時候,常常會有以下兩種需求:(有點相似於運算符中的 邏輯與 和 邏輯或)
確保全部的異步操做完成以後,才進行某個操做,只要有一個失敗,就不進行
只要有一個異步操做文章,就裏面執行某個操做。
all使用以下
若有錯誤,以下
注意:
all 方法必須
全部
的異步徹底正確
,纔會返回true,當其中一個出錯的時候,返回false,而且會將第一個出錯
的錯誤信息拋出
reac的用法
注意:
reac 方法,就是
賽跑
的意思,意思就是說,Promise.race([p1, p2, p3])裏面哪一個結果得到的快
,就返回那個結果,無論結果自己是成功狀態仍是失敗狀態。
針對第三方的promise庫,有兩個知名的庫:
以bluebird爲例,在服務端演示其用法
。
第一步,安裝
第二步,使用
本人在github中 逐步的封裝了基礎版promise
,升級版promise
,完整版的promise
,能夠進入Github中更有層次的學習原理,
Github地址:github.com/quyuandong/…
ES6 增長了一項新的內容:生成器(Generator)
。生成器是一種能夠從中退出並在以後從新進入的函數。生成器的環境(綁定的變量)會在每次執行後被保存,下次進入時可繼續使用
生成器的定義相似於
普通的函數,只是要加一個*
號,好比:function * g() { // 定義一個空生成器}
。yield
關鍵字是生成器函數中的亮點(只能在Generator函數中才能使用,普通函數中不可以使用),其字面意思爲「產出」
,每次程序執行到yield
的時候,都會「產出」一個結果。
其實Generator和 yield 兩個詞用的已經很是形象了,Generator就相似於一個工廠,每當消費者須要某種東西的時候,yield 就負責去生產,生產完了返回給消費者。
示例:
co庫地址:github.com/tj/co
$ npm install co
async/await是對Promise的優化: async/await是基於Promise的,是進一步的一種優化,不過在寫代碼時,Promise自己的API出現得不多,很接近同步代碼的寫法;
1)await只能在async函數內部使用:不能放在普通函數裏面,不然會報錯;
2)await關鍵字後面跟Promise對象:在Pending狀態時,相應的協程會交出控制權,進入等待狀態,這是協程的本質;
3)await是async wait的意思: wait的是resolve(data)的消息,並把數據data返回,
4)await後面也能夠跟同步代碼: 不過系統會自動將其轉化成一個Promsie對象,
源碼
function timeout(ms) {
return new Promise((resolve, reject) => {
setTimeout(resolve, ms, "finish");
});
}
//異步代碼
async function asyncTimeSys(){
await timeout(1000);
}
//調用方法,接收返回值
asyncTimeSys().then((value)=>{
console.log(value);
});
複製代碼