很早之前就想着学习实现一个Promise,那时候觉得一堆的高阶函数使用看不懂用不来,连简单发布订阅在实际应用都只是吃力的看懂。到了现在,硬着头皮开始学习实现一个Promise。想要编写Promise,Promise A+规范是一定要遵守的,因为所有自己实现的Promise测试通过才算是一个合格的Promise。
今天先针对自己编写过程比较重要的一些点,也算是步骤过程,对Promise A+进行一些小翻译,原谅我英语的薄弱,而且只是翻译一些小点,并不会全部翻译。
1.术语
1.1:promise是一个有then方法的对象或者函数,基本上要符合这个行为规范。
1.2:thenable是一个定义then方法的对象或者函数。
1.3:value是任何合法的JavaScript值,包括undefined、thenable、promise。
1.4:excePtion是一个抛出错误的值。
1.5:reason是一个表明promise为什么失败的值。
2.要求
2.1状态
promise必须处于三种状态之一:pending等待、fulfilled成功、rejected失败,处于等待状态的时候,可以转成成功或者失败,状态变成成功或者失败之后,就无法改变。成功有一个值,失败有一个原因。这边的不可改变。
2.2 then方法
promise必须提供then方法存取当前或者最终成功的值或者失败的原因。then方法接收两个参数:
promise.then(onFulfilled, onRejected)
2.2.1 如果两个参数不是函数,必须忽略
2.2.2
2.2.3
如果是方法,这个方法必须在promise完成之后被调用,并把promise的值作为第一个参数,在promise完成之前不能被调用,只能调用一次。
2.2.6 then在同一个promise里面可以被多次调用,且必须根据then顺序调用。
2.2.7 then必须返回一个promise
promise2 = promise1.then(onFulfilled, onRejected);
成功或者失败函数返回一个值x,运行promise Resolution Procedure,也就是判断返回值的函数(自己起名:resolvePromise)。如果成功或者失败参数不是一个函数,且promise1已经成功或者失败,promise2必须使用promise1相同的参数进行成功或者失败。
2.3 Promise Resolution Procedure函数resolvePromise
一大段的话,翻译不出来,反正就是每个人写的promise不同,但是符合规范的,我们就要大体兼容所有,就是说我们的promise如果return别人的promise,我们也要兼容,确保能使用。
2.3.1 如果promise和x是同一个对象,reject返回TypeError。
2.3.2
如果x是一个promise,x是等待状态,必须等到成功或者失败,如果是成功或者失败,用相同的return完成成功或者失败。
2.3.3
如果x是一个对象或者函数,取值then = x.then,如果x.then出错,抛出错误执行reject。如果then(这个then是then = x.then的值,下面的也都是)是一个方法,用call改变this指向,把resolve和reject当作参数传递。成功参数y,失败参数r,并调用成功失败函数。如果被调用多次,只执行第一次,或略其它调用。如果then抛出异常且成功失败被调用,调用失败方法。(跟上面x.then可以同一个try catch捕获就行)。如果x不是对象或者函数,当作普通值当作成功参数执行。如果return的是很多个promise,建议递归判断。
3注释说明
3.1
确保resolve和reject是异步的,可以采用宏任务macro-task比如 setTimeout or setImmediate,也可以采用微任务micro-task比如MutationObserver or process.nextTick。
3.4如果x符合当前规范,才认为是真正的promise,也允许一些特例
3.5先存储一个x.then的引用,任何调用这个引用,而不是多次调用x.then,预防一些意外。
大体就是这些比较重要,翻译不出全部,也翻译不准,大部分还是借助有道,还是建议百度promise a+,然后自己看看,翻译成自己理解的。