在傳統的觀念裏,我們要解決異步編程的數據傳遞往往是使用回調函數來解決。但是當我們的數據越來越多時,回調函數也會變得越來越多,這樣使得代碼雜亂無章,不利於我們的閱讀和維護。因此在ES6中給我們提供了幾種不用回調函數也能解決異步編程的數據傳遞。
Generator函數
Generator函數相當於一個狀態機,封裝了多個內部狀態。執行Generator函數會返回一個遍歷器對象,可以依次的遍歷Generator函數內部的每一個狀態。
使用方法
function* generatorFn() {
yield 'hello';
yield 'Generator';
return 'ending';
}
var gen = generatorFn();
console.log(gen.next());
console.log(gen.next());
console.log(gen.next());
定義時function
和函數名字中間有一個*
,yield
相當於阻斷器,每當函數執行到這裏時都會阻斷去執行yield
後面的代碼,next()
方法會執行下一步,並且返回yield
執行的結果
next()方法
next()
方法會執行generator
的代碼,然後,每次遇到yield x
;就返回一個對象{value: x,
done: true/false}
,然後“暫停”。返回的value
就是yield
的返回值,done
表示這個generator
是否已經執行結束了。如果done
爲true
,則value
就是return
的返回值。當執行到done
爲true
時,這個generator
對象就已經全部執行完畢,不要再繼續調用next()
了。
Promise對象
Promise 對象代表了未來將要發生的事件,用來傳遞異步操作的消息。
Promise 對象有兩個特點:
- 對象的狀態不受外界影響。Promise 對象代表一個異步操作,有三種狀態:
- pending: 初始狀態,不是成功或失敗狀態。
- fulfilled: 意味着操作成功完成。
- rejected: 意味着操作失敗。
只有異步操作的結果,可以決定當前是哪一種狀態,任何其他操作都無法改變這個狀態。這也是 Promise 這個名字的由來,它的英語意思就是「承諾」,表示其他手段無法改變。
- 一旦狀態改變,就不會再變,任何時候都可以得到這個結果。Promise 對象的狀態改變,只有兩種可能:從 Pending 變爲 Resolved 和從 Pending 變爲 Rejected。只要這兩種情況發生,狀態就凝固了,不會再變了,會一直保持這個結果。就算改變已經發生了,你再對 Promise 對象添加回調函數,也會立即得到這個結果。這與事件(Event)完全不同,事件的特點是,如果你錯過了它,再去監聽,是得不到結果的。
使用方法
let promis = new Promise(function(resolve, reject) {
setTimeout(function() {
if (1) {
resolve('成功')
} else {
reject('失敗')
}
}, 1000)
})
//一下方法可以捕獲成功和失敗後返回的數據
promis.then(function(onFulfilled, onRejected) {
console.log(onFulfilled,onRejected);
})
//以上代碼也可以這樣寫
promis.then(function(value) {
console.log(value);
}).catch(function(value) {
console.log(value);
})
async函數
async 是 ES7 纔有的與異步操作有關的關鍵字,和 Promise , Generator 有很大關聯的。他相當於Generator的語法糖。
使用方法
function fn() {
return new Promise(function(resolve) {
setTimeout(function() {
resolve('成功')
}, 1000)
})
}
async function asyncPrint() {
let first = await fn();
console.log(first);
}
asyncPrint();
//延遲1秒後輸出 成功