一、generator的基本用法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 function * generator (a ) { yield console .log (a); let b = 111 +222 ; yield a+b; let d = yield 765 +3 console .log (`d=${d} ` ) return 1234567 } let gen = generator (333 )gen.next () gen.next () gen.next () gen.next (123 )
1. for…of循环可以自动遍历generator函数运行时生成的iterator对象,且此时不需要调用next()方法。
1 2 3 4 5 6 7 8 9 10 11 12 function * foo ( ) { yield 1 ; yield 2 ; yield 3 ; yield 4 ; yield 5 ; } for (let v of foo ()) { console .log (v) }
3. g.throw(err) 在generator函数内部排除一个错误 4. g.return() 可以返回特定的值,并且终结generator函数。 5. yield* gen() 若是在generator函数内部需要调用其他generator函数,需要手动遍历,或直接使用yield*表达式。 6. 如果一个对象的属性是generator函数,则可以简写,generator的返回值是iterator遍历器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 let obj = { fun :function ( ) { }, fun1 : function * () { } } let obj = { fun () { }, *fun1 () { } }
二、async、await · async 可以用同步的方式写异步的代码,async返回的是promise
对象,如果返回了普通变量则会被包装成promise · await后面一般追加异步操作,相当于promise.then()
,如promise
对象、其他async函数
1. async/await和Promise的关系,为什么要使用async async/await是消灭异步回调的方法,有了async/await,就可以使用同步的写法去写异步的程序,不需要再用回调函数,写起来也比promise简便。 相当于promise.then promise.catch,但二者并不冲突 promise捕获错误只能用promise.catch的方法,没办法用try…catch,但async/await可以,写法上会规范许多 1 2 3 4 5 6 7 8 9 async function fn1 () { let a = Promise .reject (100 ) const res = await a console .log (res) } fn1 ()
1 2 3 4 5 6 7 8 9 10 11 12 async function fn1 () { let a = Promise .reject (100 ) try { const res = await a console .log (res) } catch (e) { console .log (`e=${e} ` ) } } fn1 ()
2. async返回一个promise,可以用.then方法,await相当于promise.then(重点!),但用法又有所不同 async函数内部return语句返回的值,会成为then方法回调函数的参数。 async自动执行、async函数返回一个 Promise 对象,可以使用then方法添加回调函数。 await 后面跟promise对象或一个一个async 函数,相当于promise.then() async函数返回的 Promise 对象,必须等到内部所有await命令后面的 Promise 对象执行完,才会发生状态改变,除非遇到return语句或者抛出错误。 也就是说,只有async函数内部的异步操作执行完,才会执行then方法指定的回调函数。
1 2 3 4 5 6 7 async function fn1 () { return 100 } fn1 == 100 fn1 ().then ((n )=> { console .log (`n=${n} ` ) })
3. 正常情况下,await命令后面是一个 Promise 对象,返回该对象的结果。如果不是 Promise 对象,就直接返回对应的值。async函数return的则是一个promise对象 1 2 3 4 5 6 async function fn1 () { let a = await 100 console .log (a) }
1 2 3 4 5 6 async function fna ( ) { let a = await Promise .resolve (100 ) }
4. await后面可以跟promise或async函数,如果跟的是一个普通函数,那加不加await都是一样的 1 2 3 4 5 6 7 8 9 10 11 12 function timeout (ms ) { return new Promise ((resolve ) => { console .log ('resolve=' ,resolve) setTimeout (()=> {resolve (100 )}, ms); }); } async function asyncPrint (value, ms ) { let a = await timeout (ms); console .log ('a=' +a) console .log (value); }
###5. async内的catch相当于promise.catch()
1 2 3 4 5 6 7 8 9 10 11 async function fn1() { try { const p4 = Promise.reject('err1') const res = await p4 console.log(res) } catch(err) { console.log(err) } } fn1() // err1
若await后面的promise状态为reject,则之后代码均不执行 1 2 3 4 5 6 7 async function fn1 ( ) { const p4 = Promise .reject ('err1' ) const res = await p4 console .log (res) } fn1 ()
5.异步的本质:遵循event-loop async/await只是语法糖,从语法层面将代码变为同步的写法,但实质是异步的,依旧基于event-loop去执行 await 后面的内容全部都理解为放在回调函数中,所以他们都是异步操作,所以要放在同步操作的后面去执行(event-loop原理)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 async function fn1 ( ) { console .log (1 ) await console .log (2 ) await console .log (3 ) await setTimeout (()=> {console .log (4 )},3000 ) console .log (5 ) await console .log (6 ) console .log (7 ) } fn1 () console .log (8 )
6.await后面加不加promise,很很很重要 不加promise相当于一个同步函数,后面的代码也是同步代码了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 function timeout(ms) { return new Promise((resolve) => { setTimeout(resolve, ms); }); } async function asyncPrint(value, ms) { await timeout(ms); console.log(value); } asyncPrint('hello world', 5000); console.log(1) // 打1,5秒后hello world // 若不加promise,会先启动定时器,立即打印1和value的值,不会等待定时器完毕再打印value // 加上promise,会先启动定时器,然后立刻打印1(同步操作),定时器结束打印value! // 声明 new Promise的时候,promise里面的函数会立马被执行,声明是同步 // 声明之后.then.catch的内容才会被放到micro task queue中
```javascript function timeout(ms) { return setTimeout(()=>{}, ms); }
async function asyncPrint(value, ms) { await timeout(ms); console.log(value); } asyncPrint(‘hello world’, 5000); console.log(1) // 立刻打1 hello world