当前位置:   article > 正文

promise的实现与原理_promise inject

promise inject

实现Promise

    Promise标准仅描述了then方法的行为,未对catchallrace方法进行描述,也未规范如何创建一个Promise对象。ES6Promise提供了以下API

(1) 构造函数

function Promise(resolver) {}

(2) 原型方法

  1. Promise.prototype.then = function() {}
  2. Promise.prototype.catch = function() {}

(3) 静态方法 

  1. Promise.resolve = function() {}
  2. Promise.reject = function() {}
  3. Promise.all = function() {}
  4. Promise.race = function() {}

 构造函数

1:  Promise/A+标准并没有指定如何构造一个Promise对象,我们以ES6原生Promise模块里通过构造函数创建Promise对象的方式实现Promise构造函数。ES6中通过构造函数创建Promise对象的简单用法如下:

  1. const promise = new Promise((resolve) => {
  2. setTimeout(()=> {
  3. resolve(1);
  4. }, 2000);
  5. });
  6. promise.then(a=> alert(a));
  7. promise.then(a => alert(a+1));

构造函数用法总结:
(1) 构造函数接收一个executor立即执行函数
(2) executor立即执行函数接收一个resolve函数
(3) promise对象的then方法绑定状态变为fulfilled时的回调
(4) resolve函数被调用时会触发then方法中的回调

  1. 构造函数的简单实现
    1. function Promise(executor) {
    2. var self = this;
    3. self.status = 'pending'; //promise当前的状态
    4. self.data = undefined; //promise的值
    5. self.onResolvedCallback = [];
    6. //promise状态变为resolve时的回调函数集,可能有多个
    7. function resolve(value) {
    8. if(self.status === 'pending') {
    9. self.status = 'resolved';
    10. self.data = value;
    11. for(var i = 0; i < self.onResolvedCallback.length; i++) {
    12. self.onResolvedCallback[i](value);
    13. }
    14. }
    15. }
    16. executor(resolve);
    17. };
    18. Promise.prototype.then = function (resolve) {
    19. this.onResolvedCallback.push(resolve);
    20. };

3. executor自执行函数接收的第二个参数为reject函数且reject函数在promise对象状态变为rejected时或executor抛出异常时触发。

  1. function Promise(executor) {
  2. var self = this;
  3. self.status = 'pending'; //promise当前的状态
  4. self.data = undefined; //promise的值
  5. self.onResolvedCallback = [];
  6. //promise状态变为resolve时的回调函数集,可能有多个
  7. self.onRejectedCallback = [];
  8. //promise状态变为reject时的回调函数集,可能有多个
  9. function resolve(value) {
  10. if(self.status === 'pending') {
  11. self.status = 'resolved';
  12. self.data = value;
  13. for(var i = 0; i < self.onResolvedCallback.length; i++) {
  14. self.onResolvedCallback[i](value);
  15. }
  16. }
  17. }
  18. function reject(reason) {
  19. if(self.status === 'pending') {
  20. self.status = 'rejected';
  21. self.data = reason;
  22. for(var i = 0; i < self.onRejectedCallback.length; i++) {
  23. self.onRejectedCallback[i](reason);
  24. }
  25. }
  26. }
  27. try {
  28. executor(resolve, reject);
  29. } catch (e){
  30. reject(e);
  31. }
  32. };
  33. Promise.prototype.then = function (onResolve, onReject) {
  34. this.onResolvedCallback.push(onResolve);
  35. this.onRejectedCallback.push(onReject);
  36. };

 

then方法

  1. 在构造函数中的示例中,then方法并没有返回一个promise对象,而 Promise/A+ 规范中规定then方法用来注册promise对象状态改变时的回调,且返回一个新的promise对象。
    (1) then方法返回一个新的promise对象。
    (2) executor自执行函数中的resolve参数调用时执行then方法的第一个回调函数onResolved
    (3) executor自执行函数中的reject参数调用时执行then方法的第二个回调函数onRejected
  1. Promise.prototype.then = function (onResolved, onRejected) {
  2. var self = this;
  3. var promise2;
  4. onResolved = typeof onResolved === 'function'
  5. ? onResolved
  6. : function (value) {return value};
  7. onRejected = typeof onRejected === 'function'
  8. ? onRejected
  9. : function (reason) {throw reason};
  10. //promise对象当前状态为resolved
  11. if(self.status === 'resolved') {
  12. return promise2 = new Promise(function (resolve, reject) {
  13. try {
  14. //调用onResolve回调函数
  15. var x = onResolved(self.data);
  16. //如果onResolve回调函数返回值为一个promise对象
  17. if(x instanceof Promise) {
  18. //将它的结果作为promise2的结果
  19. x.then(resolve, reject);
  20. } else {
  21. resolve(x);//执行promise2的onResolve回调
  22. }
  23. } catch (e) {
  24. reject(e); //执行promise2的onReject回调
  25. }
  26. })
  27. }
  28. //promise对象当前状态为rejected
  29. if(self.status === 'rejected') {
  30. return promise2 = new Promise(function (resolve, reject) {
  31. try {
  32. var x = onRejected(self.data);
  33. if (x instanceof Promise) {
  34. x.then(resolve, reject)
  35. } else {
  36. resolve(x)
  37. }
  38. } catch (e) {
  39. reject(e)
  40. }
  41. })
  42. }
  43. //promise对象当前状态为pending
  44. //此时并不能确定调用onResolved还是onRejected,需要等当前Promise状态确定。
  45. //所以需要将callBack放入promise1的回调数组中
  46. if(self.status === 'pending') {
  47. return promise2 = new Promise(function (resolve, reject) {
  48. self.onResolvedCallback.push(function (value) {
  49. try {
  50. var x = onResolved(self.data);
  51. if (x instanceof Promise) {
  52. x.then(resolve, reject);
  53. } else {
  54. resolve(x);
  55. }
  56. } catch (e) {
  57. reject(e);
  58. }
  59. })
  60. self.onRejectedCallback.push(function(reason) {
  61. try {
  62. var x = onRejected(self.data);
  63. if (x instanceof Promise) {
  64. x.then(resolve, reject)
  65. } else {
  66. resolve(x);
  67. }
  68. } catch (e) {
  69. reject(e)
  70. }
  71. })
  72. })
  73. }
  74. };

完整代码

  1. var Promise = (function() {
  2. function Promise(resolver) {
  3. if (typeof resolver !== 'function') { //resolver必须是函数
  4. throw new TypeError('Promise resolver ' + resolver + ' is not a function')
  5. }
  6. if (!(this instanceof Promise)) return new Promise(resolver)
  7. var self = this //保存this
  8. self.callbacks = [] //保存onResolve和onReject函数集合
  9. self.status = 'pending' //当前状态
  10. function resolve(value) {
  11. setTimeout(function() { //异步调用
  12. if (self.status !== 'pending') {
  13. return
  14. }
  15. self.status = 'resolved' //修改状态
  16. self.data = value
  17. for (var i = 0; i < self.callbacks.length; i++) {
  18. self.callbacks[i].onResolved(value)
  19. }
  20. })
  21. }
  22. function reject(reason) {
  23. setTimeout(function(){ //异步调用
  24. if (self.status !== 'pending') {
  25. return
  26. }
  27. self.status = 'rejected' //修改状态
  28. self.data = reason
  29. for (var i = 0; i < self.callbacks.length; i++) {
  30. self.callbacks[i].onRejected(reason)
  31. }
  32. })
  33. }
  34. try{
  35. resolver(resolve, reject) //执行resolver函数
  36. } catch(e) {
  37. reject(e)
  38. }
  39. }
  40. function resolvePromise(promise, x, resolve, reject) {
  41. var then
  42. var thenCalledOrThrow = false
  43. if (promise === x) {
  44. return reject(new TypeError('Chaining cycle detected for promise!'))
  45. }
  46. if ((x !== null) && ((typeof x === 'object') || (typeof x === 'function'))) {
  47. try {
  48. then = x.then
  49. if (typeof then === 'function') {
  50. then.call(x, function rs(y) {
  51. if (thenCalledOrThrow) return
  52. thenCalledOrThrow = true
  53. return resolvePromise(promise, y, resolve, reject)
  54. }, function rj(r) {
  55. if (thenCalledOrThrow) return
  56. thenCalledOrThrow = true
  57. return reject(r)
  58. })
  59. } else {
  60. return resolve(x)
  61. }
  62. } catch(e) {
  63. if (thenCalledOrThrow) return
  64. thenCalledOrThrow = true
  65. return reject(e)
  66. }
  67. } else {
  68. return resolve(x)
  69. }
  70. }
  71. Promise.prototype.then = function(onResolved, onRejected) {
  72. //健壮性处理,处理点击穿透
  73. onResolved = typeof onResolved === 'function' ? onResolved : function(v){return v}
  74. onRejected = typeof onRejected === 'function' ? onRejected : function(r){throw r}
  75. var self = this
  76. var promise2
  77. //promise状态为resolved
  78. if (self.status === 'resolved') {
  79. return promise2 = new Promise(function(resolve, reject) {
  80. setTimeout(function() {
  81. try {
  82. //调用then方法的onResolved回调
  83. var x = onResolved(self.data)
  84. //根据x的值修改promise2的状态
  85. resolvePromise(promise2, x, resolve, reject)
  86. } catch(e) {
  87. //promise2状态变为rejected
  88. return reject(e)
  89. }
  90. })
  91. })
  92. }
  93. //promise状态为rejected
  94. if (self.status === 'rejected') {
  95. return promise2 = new Promise(function(resolve, reject) {
  96. setTimeout(function() {
  97. try {
  98. //调用then方法的onReject回调
  99. var x = onRejected(self.data)
  100. //根据x的值修改promise2的状态
  101. resolvePromise(promise2, x, resolve, reject)
  102. } catch(e) {
  103. //promise2状态变为rejected
  104. return reject(e)
  105. }
  106. })
  107. })
  108. }
  109. //promise状态为pending
  110. //需要等待promise的状态改变
  111. if (self.status === 'pending') {
  112. return promise2 = new Promise(function(resolve, reject) {
  113. self.callbacks.push({
  114. onResolved: function(value) {
  115. try {
  116. //调用then方法的onResolved回调
  117. var x = onResolved(value)
  118. //根据x的值修改promise2的状态
  119. resolvePromise(promise2, x, resolve, reject)
  120. } catch(e) {
  121. //promise2状态变为rejected
  122. return reject(e)
  123. }
  124. },
  125. onRejected: function(reason) {
  126. try {
  127. //调用then方法的onResolved回调
  128. var x = onRejected(reason)
  129. //根据x的值修改promise2的状态
  130. resolvePromise(promise2, x, resolve, reject)
  131. } catch(e) {
  132. //promise2状态变为rejected
  133. return reject(e)
  134. }
  135. }
  136. })
  137. })
  138. }
  139. }
  140. //获取当前Promise传递的值
  141. Promise.prototype.valueOf = function() {
  142. return this.data
  143. }
  144. //then方法实现catch方法
  145. Promise.prototype.catch = function(onRejected) {
  146. return this.then(null, onRejected)
  147. }
  148. //finally方法
  149. Promise.prototype.finally = function(fn) {
  150. return this.then(function(v){
  151. setTimeout(fn)
  152. return v
  153. }, function(r){
  154. setTimeout(fn)
  155. throw r
  156. })
  157. }
  158. Promise.prototype.spread = function(fn, onRejected) {
  159. return this.then(function(values) {
  160. return fn.apply(null, values)
  161. }, onRejected)
  162. }
  163. Promise.prototype.inject = function(fn, onRejected) {
  164. return this.then(function(v) {
  165. return fn.apply(null, fn.toString().match(/\((.*?)\)/)[1].split(',').map(function(key){
  166. return v[key];
  167. }))
  168. }, onRejected)
  169. }
  170. Promise.prototype.delay = function(duration) {
  171. return this.then(function(value) {
  172. return new Promise(function(resolve, reject) {
  173. setTimeout(function() {
  174. resolve(value)
  175. }, duration)
  176. })
  177. }, function(reason) {
  178. return new Promise(function(resolve, reject) {
  179. setTimeout(function() {
  180. reject(reason)
  181. }, duration)
  182. })
  183. })
  184. }
  185. Promise.all = function(promises) {
  186. return new Promise(function(resolve, reject) {
  187. var resolvedCounter = 0
  188. var promiseNum = promises.length
  189. var resolvedValues = new Array(promiseNum)
  190. for (var i = 0; i < promiseNum; i++) {
  191. (function(i) {
  192. Promise.resolve(promises[i]).then(function(value) {
  193. resolvedCounter++
  194. resolvedValues[i] = value
  195. if (resolvedCounter == promiseNum) {
  196. return resolve(resolvedValues)
  197. }
  198. }, function(reason) {
  199. return reject(reason)
  200. })
  201. })(i)
  202. }
  203. })
  204. }
  205. Promise.race = function(promises) {
  206. return new Promise(function(resolve, reject) {
  207. for (var i = 0; i < promises.length; i++) {
  208. Promise.resolve(promises[i]).then(function(value) {
  209. return resolve(value)
  210. }, function(reason) {
  211. return reject(reason)
  212. })
  213. }
  214. })
  215. }
  216. Promise.resolve = function(value) {
  217. var promise = new Promise(function(resolve, reject) {
  218. resolvePromise(promise, value, resolve, reject)
  219. })
  220. return promise
  221. }
  222. Promise.reject = function(reason) {
  223. return new Promise(function(resolve, reject) {
  224. reject(reason)
  225. })
  226. }
  227. Promise.fcall = function(fn){
  228. // 虽然fn可以接收到上一层then里传来的参数,但是其实是undefined,所以跟没有是一样的,因为resolve没参数啊
  229. return Promise.resolve().then(fn)
  230. }
  231. Promise.done = Promise.stop = function(){
  232. return new Promise(function(){})
  233. }
  234. Promise.deferred = Promise.defer = function() {
  235. var dfd = {}
  236. dfd.promise = new Promise(function(resolve, reject) {
  237. dfd.resolve = resolve
  238. dfd.reject = reject
  239. })
  240. return dfd
  241. }
  242. try { // CommonJS compliance
  243. module.exports = Promise
  244. } catch(e) {}
  245. return Promise
  246. })()

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/786694
推荐阅读
相关标签
  

闽ICP备14008679号