持续更新中......
ES6
Promise
// Promise 新建后就会立即执行
const promise = new Promise((resolve,reject)=>{
// some code
if(/*操作成功*/){
// pending->resolved
resolve(data);
}else {
// pending->rejected
reject(data);
}
})
// 回调
promise().then(data=>{
console.log(data)
})
Promise可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数,为Promise对象提供了统一的接口,使得控制更容易
缺点:无法中途取消Promise,一旦新建就会执行;如果不设置回调函数,不会主动抛出异常;无法得知pending处于具体何种状态,比如刚开始,还是即将完成
Generator
function* ExampleGenerator(){
yield 'hello~';
yield 'king';
return 'bye~'
}
let eg = ExampleGenerator();
eg.next(); // {value: "hello~", done: false}
eg.next(); // {value: "king", done: false}
eg.next(); // {value: "bye~", done: true}
eg.next(); // {value: undefined, done: true}
Generator被调用之后,并不会被执行,返回的也不是函数运行结果,而是一个指向内部状态的指针对象(遍历器Iterator对象),Generator 函数可以理解为是一个状态机,封装了多个内部状态
-
yield表达式
-
只能用在 Generator 函数里面,用在其他地方都会报错;Generator 函数可以不用yield表达式,这时就变成了一个单纯的暂缓执行函数
-
与return语句既有相似之处,也有区别。相似之处在于,都能返回紧跟在语句后面的那个表达式的值。区别在于每次遇到yield,函数暂停执行,下一次再从该位置继续向后执行,而return语句不具备位置记忆的功能;一个函数里面只能执行一次return,yield可以执行很多次
-
-
next()方法
-
next(params)参数表示上一个yield表达式的返回值,所以第一次使用next时传参是无效的,从语义上讲,第一个next方法用来启动遍历器对象,所以不用带有参数
-
这个功能有很重要的语法意义。Generator 函数从暂停状态到恢复运行,它的上下文状态(context)是不变的。通过next方法的参数,就有办法在 Generator 函数开始运行之后,继续向函数体内部注入值。也就是说,可以在 Generator 函数运行的不同阶段,从外部向内部注入不同的值,从而调整函数行为。
-
持续更新中......
async
async是Generator 函数的语法糖,ES2017 标准引入了 async 函数,使得异步操作变得更加方便
const asy = async function(){
let a = await 'hello';
let b = await 'bye';
console.log(a);
console.log(b);
}
asy(); // 'hello' 'bye'
与Generator区别
-
内置执行器。Generator 函数的执行必须靠执行器,所以才有了co模块,而async函数自带执行器。也就是说,async函数的执行,与普通函数一模一样,只要一行。
-
更好的语义。async和await,比起星号和yield,语义更清楚了。async表示函数里有异步操作,await表示紧跟在后面的表达式需要等待结果
-
更广的适用性。co模块约定,yield命令后面只能是 Thunk 函数或 Promise 对象,而async函数的await命令后面,可以是 Promise 对象和原始类型的值(数值、字符串和布尔值,但这时会自动转成立即 resolved 的 Promise 对象)
-
返回值是 Promise。async函数的返回值是 Promise 对象,这比 Generator 函数的返回值是 Iterator 对象方便多了。你可以用then方法指定下一步的操作。
进一步说,async函数完全可以看作多个异步操作,包装成的一个 Promise 对象,而await命令就是内部then命令的语法糖
网友评论