Promise
Promise对象
JavaScript
是单线程的语言,通过维护执行栈与任务队列而实现了异步操作,setTimeout
与Ajax
就是典型的异步操作,Promise
就是异步操作的一个解决方案,用于表示一个异步操作的最终完成或失败及其结果值,Promise
有各种开源实现,在ES6
中被统一规范,由浏览器直接支持。
语法
1 | new Promise( function(resolve, reject) { /* executor */ |
executor
是带有resolve
和reject
两个参数的函数。Promise
构造函数执行时立即调用executor
函数,resolve
和reject
两个函数作为参数传递给executor
。resolve
和reject
函数被调用时,分别将promise
的状态改为完成fulfilled
或失败rejected
。executor
内部通常会执行一些异步操作,一旦异步操作执行完毕,要么调用resolve
函数来将promise
状态改成fulfilled
,要么调用reject
函数将promise
的状态改为rejected
。如果在executor
函数中抛出一个错误,那么该promise
状态为rejected
,executor
函数的返回值被忽略。
状态
1 | pending: 初始状态,既不是成功,也不是失败状态。 |
Promise
对象只有从pending
变为fulfilled
和从pending
变为rejected
的状态改变。只要处于fulfilled
和rejected
,状态就不会再变了。
缺点:无法取消Promise
,一旦新建它就会立即执行,无法中途取消;如果不主动catch
,Promise
内部抛出的异常,不会反应到外部,在FireFox
中异常不会抛出,在Chrome
中的异常抛出但不会触发winodw.onerror
事件;当处于pending
状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)。
实例
Promise
可以进行链式调用,避免过多的异步操作造成的回调地狱,then()
函数默认会返回一个和原来不同的新的Promise
。
1 | var promise = new Promise(function(resolve,reject){ |
进行多次异步操作,假设只有resolve
才会进行下一步异步操作
1 | var promise = new Promise(function(resolve,reject){ |
使用catch
捕捉异常
1 | var promise = new Promise(function(resolve,reject){ |
then
本身可以接受两个参数resolve
与reject
1 | var promise = new Promise(function(resolve,reject){ |
方法
Promise.all(iterable)
这个方法返回一个新的promise
对象,该promise
对象在iterable
参数对象里所有的promise
对象都成功的时候才会触发成功,一旦有任何一个iterable
里面的promise
对象失败则立即触发该promise
对象的失败。这个新的promise
对象在触发成功状态以后,会把一个包含iterable
里所有promise
返回值的数组作为成功回调的返回值,顺序跟iterable
的顺序保持一致;如果这个新的promise
对象触发了失败状态,它会把iterable
里第一个触发失败的promise
对象的错误信息作为它的失败错误信息。Promise.all
方法常被用于处理多个promise
对象的状态集合。
1 | var p1 = new Promise((resolve, reject) => { |
Promise.race(iterable)
当iterable
参数里的任意一个子promise
被成功或失败后,父promise
马上也会用子promise
的成功返回值或失败详情作为参数调用父promise
绑定的相应句柄,并返回该promise
对象。
1 | var p1 = new Promise((resolve, reject) => { |
Promise.resolve(value)
返回一个状态由给定value
决定的Promise
对象。如果该值是thenable
(即,带有then
方法的对象),返回的Promise
对象的最终状态由then
方法执行决定;否则的话(该value
为空,基本类型或者不带then
方法的对象),返回的Promise
对象状态为fulfilled
,并且将该value
传递给对应的then
方法。通常而言,如果你不知道一个值是否是Promise
对象,使用Promise.resolve(value)
来返回一个Promise
对象,这样就能将该value
以Promise
对象形式使用。不要在解析为自身的thenable
上调用Promise.resolve
,这将导致无限递归,因为它试图展平无限嵌套的promise
。
1 | // 该值为空或基本类型,直接返回一个fulfilled状态的Promise对象 |
Promise.reject(reason)
返回一个状态为失败的Promise
对象,并将给定的失败信息传递给对应的处理方法
1 | var promise = Promise.reject("err"); |
原型方法
Promise.prototype.then(onFulfilled, onRejected)
添加解决fulfillment
和拒绝rejection
回调到当前promise
,返回一个新的promise
,将以回调的返回值来resolve
。
Promise.prototype.catch(onRejected)
添加一个拒绝rejection
回调到当前promise
,返回一个新的promise
。当这个回调函数被调用,新promise
将以它的返回值来resolve
,否则如果当前promise
进入fulfilled
状态,则以当前promise
的完成结果作为新promise
的完成结果。
Promise.prototype.finally(onFinally)
添加一个事件处理回调于当前promise
对象,并且在原promise
对象解析完毕后,返回一个新的promise
对象。回调会在当前promise
运行完毕后被调用,无论当前promise
的状态是完成fulfilled
还是失败rejected
。
实现Ajax
1 | function ajax(method, url, data) { |
参考
1 | https://www.liaoxuefeng.com/wiki/1022910821149312/1023024413276544 |