es6學習之Generator函式,async函式
阿新 • • 發佈:2019-01-28
一.Generator函式的語法
1.概念和語法
(1)概念
Generator是一個狀態機,內部封裝多個狀態 ;
Generator會返回一個遍歷器,呼叫Generator的next方法可以依次執行
(2)語法
(1) function後面跟著*號,呼叫函式不會立即執行Generator函式,只有呼叫next方法的時候才會執行. next方法在yield表示式處停止,next返回一個物件,當value是undefined,done是true的時候,就結束了.
(2) next方法可以傳入引數,也可以不傳入,傳入的引數當作上一個yield表示式的返回值 . 這個功能能夠在Generator函式執行的各個階段傳入不同的值,進而有不同的行為.
(3) 可以使用for…of迴圈,到返回done為true時結束,也就是return 的結果不會被for…of捕獲
function* helloWorldGenerator() {
yield 'hello';
yield 'world';
return 'ending';
}
var hw = helloWorldGenerator();
// 使用next方法
hw.next(); // {value: "hello", done: false}
hw.next(); // {value: "world", done: false}
hw.next(); // {value: "ending", done: true}
hw.next(); // {value: undefined, done: true }
hw.next(); // {value: undefined, done: true}
// 使用for迴圈,上面的next方法不能和for...of一起使用,因為狀態已經執行過了便固定了
for (let value of hw) {
console.log('value',value);
}
// value hello
// value world
2.Generator的函式方法
(1)Generator.prototype.throw()
- 每一個Generator返回的遍歷器物件都有一個throw方法,不同於全域性的throw方法,它能在Generator中宣告try…catch,在遍歷的時候呼叫遍歷物件的throw方法,被Generator內部捕獲,但是外部物件throw一次,內部一個catch只能一次
- 對用遍歷器物件的throw方法,會預設執行一次next方法
var g = function* () {
try {
yield;
} catch (e) {
console.log('內部捕獲', e);
}
};
var i = g();
i.next();
try {
i.throw('a');
i.throw('b');
} catch (e) {
console.log('外部捕獲', e);
}
// 內部捕獲 a
// 外部捕獲 b
(2)Generator.prototype.return()
遍歷器物件上還有一個return的方法,可以結束遍歷,即使下面還沒有遍歷結束 . 返回的引數的value時return方法的引數(如無引數則value=undefined),done為true,
如果Generator內有finally結構,則return方法會被推遲到finally執行完畢後執行
function* numbers () {
yield 1;
try {
yield 2;
yield 3;
} finally {
yield 4;
yield 5;
}
yield 6;
}
var g = numbers();
g.next() // { value: 1, done: false }
g.next() // { value: 2, done: false }
g.return(7) // { value: 4, done: false }
g.next() // { value: 5, done: false }
g.next() // { value: 7, done: true }
(3)yield*表示式
在一個Generator的函式內部呼叫另一個Generator函式,另一個函式返回的是一個遍歷器物件
function* bar() {
yield 'x';
yield* foo();
yield 'y';
}
// 等同於
function* bar() {
yield 'x';
yield 'a';
yield 'b';
yield 'y';
}
// 等同於
function* bar() {
yield 'x';
for (let v of foo()) {
yield v;
}
yield 'y';
}
for (let v of bar()){
console.log(v);
}
// "x"
// "a"
// "b"
// "y"
二.async函式
1.概念和語法
(1)概念
asyn函式就是Generator函式的語法糖,等待await後面的函式完成之後在執行下面的語句 .
async函式返回Promise,
(2)語法
function fun1 () {
setTimeout(()=>{
console.log('fun1');
},2000);
}
function fun2 () {
setTimeout(()=>{
console.log('fun2');
},3000);
}
const asyncFun = async function () {
let f1 = await fun1();
let f2 = await fun2();
console.log(f1);
console.log(f2);
}
asyncFun();
// 2秒後列印fun1
// 3秒後列印fun2
// 返回Promise
async function f() {
return 'hello world';
}
f().then(v => console.log(v))
// "hello world"
2.async的函式語法
- 返回Promise
- Promise狀態的變化是當內部的所有await執行完才會改變,除非遇到return或者錯誤
- 所有的await命令最好都放在try…catch中,否則一個await的promise變為reject就會終端async中的所有await命令