前端开发中会遇到某些场景存在异步问题,比如从后端请求到数据以后才能继续往下执行某函数,最常见的写法是将函数调用写在请求数据的回调函数里,待请求函数执行完毕后再执行下面的函数,但是此方法有一弊端就是若业务逻辑太过复杂时,会一层层使用回调 ,使得代码可读性与维护性变得很差(回调地狱)。
promise:es6提供了原生的promise对象,promise对象代表了未来将要发生的事件,用来传递异步操作的消息
两个特点:
1、不受外界影响,代表一个异步操作,有三种状态:pending(初始状态非成功与失败状态),fulfilled(操作成功状态),rejected(失败状态)
2、一旦状态改变就不会再变:只有两种情况,从pending变为resolveed或者从pending变为rejected状态,只要发生就不再改变
优缺点:优点是避免了层层嵌套的回调函数, promise对象还提供了提供了统一的接口,使控制异步操作更加容易
缺点是无法取消Promise,一旦新建就必须完成,若不设置回调函数,promise内部返回的错误就不会反应到外部,当处于pending状态时,无法得知目前进行到了那个阶段
promise的创建:
promise.then(onFulfilled, onRejected);promise简化了错误处理的方法,我们也可以这样写:promise.then(onFulfilled).catch(onRejected)
链式操作:Promise.prototype.then返回的是一个新的Promise对象,因此可以采用链式写法
Promise.proptype.catch方法捕捉错误:
Promise.prototype.catch 方法是 Promise.prototype.then(null, rejection) 的别名,用于指定发生错误时的回调函数。
Promise 对象的错误具有"冒泡"性质,会一直向后传递,直到被捕获为止。也就是说,错误总是会被下一个 catch 语句捕获。
Promise.all方法:Promise.all 方法用于将多个 Promise 实例,包装成一个新的 Promise 实例。
var p = Promise.all([p1,p2,p3]);
上面代码中,Promise.all 方法接受一个数组作为参数,p1、p2、p3 都是 Promise 对象的实例。(Promise.all 方法的参数不一定是数组,但是必须具有 iterator 接口,且返回的每个成员都是 Promise 实例。)
p 的状态由 p1、p2、p3 决定,分成两种情况。
(1)只有p1、p2、p3的状态都变成fulfilled,p的状态才会变成fulfilled,此时p1、p2、p3的返回值组成一个数组,传递给p的回调函数。
(2)只要p1、p2、p3之中有一个被rejected,p的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数。
Promise.race 方法同样是将多个 Promise 实例,包装成一个新的 Promise 实例。
var p = Promise.race([p1,p2,p3]);
上面代码中,只要p1、p2、p3之中有一个实例率先改变状态,p的状态就跟着改变。那个率先改变的Promise实例的返回值,就传递给p的返回值。
Generator:ES6 新引入了 Generator 函数,可以通过 yield 关键字,把函数的执行流挂起,为改变执行流程提供了可能,从而为异步编程提供解决方案。
Generator 有两个区分于普通函数的部分:
一是在 function 后面,函数名之前有个 * ;
函数内部有 yield 表达式。
其中 * 用来表示函数为 Generator 函数,yield 用来定义函数内部的状态。
执行机制
调用 Generator 函数和调用普通函数一样,在函数名后面加上()即可,但是 Generator 函数不会像普通函数一样立即执行,而是返回一个指向内部状态对象的指针,所以要调用遍历器对象Iterator 的 next 方法,指针就会从函数头部或者上一次停下来的地方开始执行。
throw 方法:
async方法
async 是 ES7 才有的与异步操作有关的关键字,和 Promise , Generator 有很大关联的。
async 函数中可能会有 await 表达式,async 函数执行时,如果遇到 await 就会先暂停执行 ,等到触发的异步操作完成后,恢复 async 函数的执行并返回解析值。
返回值:返回 Promise 对象的处理结果。如果等待的不是 Promise 对象,则返回该值本身。
如果一个 Promise 被传递给一个 await 操作符,await 将等待 Promise 正常处理完成并返回其处理结果。
await 命令后面是一个 Promise 对象,它也可以跟其他值,如字符串,布尔值,数值以及普通函数。
本文部分内容参考自菜鸟教程ES6教程