promise作为前端异步的解决方案,几乎所有的前端甚至框架都有他的身影。
为什么会有promise
为了解决回调地狱的问题。
回调地狱指的是多层嵌套的问题,每种任务处理结果都有两种可能性,成功或者失败,那么需要在每种任务执行结束以后分别处理两种可能性。
怎么实现promise
遵循promise a+规范
1.promise是一个类,类中需要传入executor执行器,默认会立即执行。
new Promise(() => {
console.log(1);
});
2.promise有两个方法,这两个方法会传给用户,可以更改promise状态。
3.promise有三个状态
等待
成功
返回成功的结果,如果不写结果返回undefined
失败
返回失败的原因,如果不写,返回undefined
4.promise只会从等待变为成功或者从等待变为失败。
5.每一个promise实例实际上都有一个then的方法,分别是成功和失败的回调。
一个promise必须提供一个then方法获取其值或原因,promise的then方法接受两个参数
promise.then(onFulfilled, onRejected)
1.onFulfilled
和onRejected
是可选参数。
如果onFulfilled不是一个参数,则忽略之。
如果onRejected不是一个参数,则忽略之。
2.如果onFulfilled是一个函数。
它必须在promise
fulfilled
后调用,且promise
的value
为其第一个参数
它不能在promise
fulfilled
前调用
不能被多次调用
3.如果onRejected
是一个函数
它必须在promise
rejected
后调用,且promise
的reason
为其第一个参数
它不能在promise rejected
前调用
不能被多次调用
4.onFulfilled
和onRejected
只允许在execution context
栈仅包含平台代码时运行
5.onFulfilled
和onRejected
必须被当做函数调用 (i.e. 即函数体内的this
为undefined
)
6.对于一个promise
,它的then
方法可以调用多次
当promise fulfilled
后,所有onFulfilled
都必须按照其注册顺序执行
当promise rejected
后,所有OnRejected
都必须按照其注册顺序执行
then
必须返回一个promise
[3.3]
如果onFulfilled
或 onRejected
返回了值x
, 则执行Promise
解析流程[[Resolve]](promise2, x)
如果onFulfilled
或 onRejected
抛出了异常e, 则promise2
应当以e为reason
被拒绝。
如果 onFulfilled
不是一个函数且promise1
已经fulfilled
,则promise2
必须以promise1
的值fulfilled.
如果 OnReject
不是一个函数且promise1
已经rejected
, 则promise2
必须以相同的reason
被拒绝.
jspromise2 = promise1.then(onFulfilled, onRejected);
promise的解析过程
Promise解析过程 是以一个promise和一个值做为参数的抽象过程,可表示为[[Resolve]](promise, x). 过程如下;
如果promise 和 x 指向相同的值, 使用 TypeError做为原因将promise拒绝。
如果 x 是一个promise, 采用其状态 [3.4]
如果x是pending状态,promise必须保持pending走到x fulfilled或rejected
如果x是fulfilled状态,将x的值用于fulfill promise
如果x是rejected状态, 将x的原因用于reject promise
如果x是一个对象或一个函数
将 then 赋为 x.then. [3.5]
如果在取x.then值时抛出了异常,则以这个异常做为原因将promise拒绝
如果 then 是一个函数, 以x为this调用then函数, 且第一个参数是resolvePromise,第二个参数是rejectPromise,且:
当 resolvePromise 被以 y为参数调用, 执行 [[Resolve]](promise, y).
当 rejectPromise 被以 r 为参数调用, 则以r为原因将promise拒
如果 resolvePromise 和 rejectPromise 都被调用了,或者被调用了多次,则只第一次有效,后面的忽略。
如果在调用then时抛出了异常,则
如果 resolvePromise 或 rejectPromise 已经被调用了,则忽略它
否则, 以e为reason将 promise 拒绝