promise

time 2m41s

  1. class MyPromise {
  2. constructor() {
  3. }
  4. }
  5. /*换成mypromise*/
  6. // const p1 = new Promise((resolve, reject) => {
  7. const p1 = new MyPromise((resolve, reject) => {
  8. resolve(1);
  9. })
  10. p1.then((res) => {
  11. console.log(res);
  12. }, err => {
  13. console.log(err);
  14. })
  15. /*1*/

第一步

time 5m54s

  1. class MyPromise {
  2. constructor(executor) {
  3. this.state = 'pending';
  4. this.value = undefined;
  5. this.reason = undefined;
  6. let resolve = (value) => {
  7. this.state = 'fullFilled';
  8. this.value = value
  9. }
  10. let reject = (reason) => {
  11. this.state = 'rejected';
  12. this.reason = reason;
  13. }
  14. executor(resolve, reject);
  15. }
  16. then(onFullFilled, onRejected) {
  17. if (this.state === 'fullFilled') {
  18. onFullFilled(this.value);
  19. }
  20. if (this.state === 'rejected') {
  21. onRejected(this.reason);
  22. }
  23. }
  24. }
  25. /*换成mypromise*/
  26. // const p1 = new Promise((resolve, reject) => {
  27. const p1 = new MyPromise((resolve, reject) => {
  28. resolve(1);
  29. })
  30. p1.then((res) => {
  31. console.log(res);
  32. }, err => {
  33. console.log(err);
  34. })
  35. /*1*/

分析

1可以new MyPromise(参数xx),说明需要在constructor构造函数中写,定义
先把需要的方法、参数写了。参数executor,resolve, reject。参数是什么?是方法,补上resolve,reject,不然报错,补上then方法,使得函数运行不报错
2方法有了,需要干什么有了,之后需要数据,开始声明变量,this.变量可以使得在构造函数声明的变量,在构造函数外也可以使用,在then方法中也可以使用
state变量用来记录状态信息,记录状态数据,value储存resolve传入的value的值,同理
3then方法分析p1.then,传入的是两个参数, then(onFullFilled, onRejected)先写上,两个回调函数onFullFilled(this.value),判断state走相应的回调函数,

  1. p1.then((res) => {
  2. console.log(res);
  3. }, err => {
  4. console.log(err);
  5. })

这时传到两个函数,是作为参数,作为实参传入,并不会在p1.then的时候运行,是交给p1去调用,不是直接运行。
p1调用两个回调函数,决定它们何时运行,运不运行,err的可能都不会运行,传入的实参,不一定会运行

promise是一个控制方法运行的东西,的容器,实际运行的方法,实际的方法成千上万,有各种各样的方法,这些都是传入的回调函数决定的,promise只管控制它们。具体方法的实现不管。

处理异步

time 6m35s

  1. class MyPromise {
  2. constructor(executor) {
  3. this.state = 'pending';
  4. this.value = undefined;
  5. this.reason = undefined;
  6. this.onFullFilledCallbacks = [];
  7. this.onRejectedCallbacks = [];
  8. let resolve = (value) => {
  9. this.state = 'fullFilled';
  10. this.value = value;
  11. // this.onFullFilledCallbacks.forEach(fn => fn(this.value));
  12. this.onFullFilledCallbacks.forEach(fn => fn());
  13. }
  14. let reject = (reason) => {
  15. this.state = 'rejected';
  16. this.reason = reason;
  17. // this.onRejectedCallbacks.forEach(fn => fn(this.value));
  18. this.onRejectedCallbacks.forEach(fn => fn());
  19. }
  20. executor(resolve, reject);
  21. }
  22. then(onFullFilled, onRejected) {
  23. if (this.state === 'fullFilled') {
  24. onFullFilled(this.value);
  25. }
  26. if (this.state === 'rejected') {
  27. onRejected(this.reason);
  28. }
  29. if (this.state === 'pending') {
  30. /* this.onFullFilledCallbacks.push(onFullFilled);
  31. this.onRejectedCallbacks.push(onRejected);*/
  32. this.onFullFilledCallbacks.push(() => {
  33. onFullFilled(this.value);
  34. });
  35. this.onRejectedCallbacks.push(()=>{
  36. onRejected(this.reason);
  37. });
  38. }
  39. }
  40. }
  41. /*换成mypromise*/
  42. // const p1 = new Promise((resolve, reject) => {
  43. const p1 = new MyPromise((resolve, reject) => {
  44. setTimeout(() => {
  45. resolve(1);
  46. }, 1000)
  47. })
  48. p1.then((res) => {
  49. console.log(res);
  50. }, err => {
  51. console.log(err);
  52. })
  53. p1.then((res) => {
  54. console.log(res);
  55. }, err => {
  56. console.log(err);
  57. })
  58. /*1 1*/

解析思路

因为异步操作setTimeout运行时,p1这是其实并没有运行完成
如同

  1. let a = () => {
  2. setTimeout(() => {
  3. return 1;
  4. })
  5. }
  6. let n = a();
  7. console.log(n)
  8. /*undefined*/

打印undefined,因为let a声明,let n声明赋值,console是同步代码,先运行
setTimeout后运行,等它们运行完之后再运行。

let n声明赋值不会等待a()里面的setTimeout运行完了,返回值了之后再去运行,所以只能拿到undefined
let n = a();运行n=undefined,之后console运行,同步代码等待执行

怎么解决这个问题?
不运行,而是放入数组

  1. if (this.state === 'pending') {
  2. /* this.onFullFilledCallbacks.push(onFullFilled);
  3. this.onRejectedCallbacks.push(onRejected);*/
  4. this.onFullFilledCallbacks.push(() => {
  5. onFullFilled(this.value);
  6. });
  7. this.onRejectedCallbacks.push(()=>{
  8. onRejected(this.reason);
  9. });
  10. }

异步情况,state明显是pedding,把回调函数与参数放入方法中,把回调函数运行放入方法中,方法不运行,回调函数也不会直接运行,用方法存储回调函数的运行,为了以后可以运行,之后运行这个函数,就可以直接运行回调函数了,不用传参,不管最后运不运行都要放进去,防止万一运行,万一之后用到
用数组放入函数,为了防止多个p1.then调用

onFullFilled(this.value)的value是实参,实参是在resolve(1);时传入的

这里面res是形参,不是传入的数据

  1. p1.then((res) => {
  2. console.log(res);
  3. }, err => {
  4. console.log(err);
  5. })

再通过 this.onFullFilledCallbacks.forEach(fn => fn());遍历函数让其运行

  1. let resolve = (value) => {
  2. this.state = 'fullFilled';
  3. this.value = value;
  4. // this.onFullFilledCallbacks.forEach(fn => fn(this.value));
  5. this.onFullFilledCallbacks.forEach(fn => fn());
  6. }

此时then是存入回调函数不运行,运行不由then控制
resolve(1);控制运行传入的回调函数,等setTimeout运行完,resolve运行

步骤

1pedding情况的建立
2两个储存回调数组的建立
3数组储存回调方法
4从数组中提取方法

处理链式操作

time 10m20s

  1. class MyPromise {
  2. constructor(executor) {
  3. this.state = 'pending';
  4. this.value = undefined;
  5. this.reason = undefined;
  6. this.onFullFilledCallbacks = [];
  7. this.onRejectedCallbacks = [];
  8. let resolve = (value) => {
  9. this.state = 'fullFilled';
  10. this.value = value;
  11. // this.onFullFilledCallbacks.forEach(fn => fn(this.value));
  12. this.onFullFilledCallbacks.forEach(fn => fn());
  13. }
  14. let reject = (reason) => {
  15. this.state = 'rejected';
  16. this.reason = reason;
  17. // this.onRejectedCallbacks.forEach(fn => fn(this.value));
  18. this.onRejectedCallbacks.forEach(fn => fn());
  19. }
  20. executor(resolve, reject);
  21. }
  22. then(onFullFilled, onRejected) {
  23. let x;
  24. /*因为判断是同步执行的*/
  25. const p2 = new MyPromise((resolve, reject) => {
  26. if (this.state === 'fullFilled') {
  27. x = onFullFilled(this.value);
  28. // console.log('165:'+x)
  29. resolve(x);
  30. }
  31. if (this.state === 'rejected') {
  32. x = onRejected(this.reason);
  33. resolve(x);
  34. }
  35. if (this.state === 'pending') {
  36. /* this.onFullFilledCallbacks.push(onFullFilled);
  37. this.onRejectedCallbacks.push(onRejected);*/
  38. this.onFullFilledCallbacks.push(() => {
  39. x= onFullFilled(this.value);
  40. resolve(x);
  41. });
  42. this.onRejectedCallbacks.push(() => {
  43. x= onRejected(this.reason);
  44. resolve(x);
  45. });
  46. }
  47. })
  48. return p2;
  49. }
  50. }
  51. /*换成mypromise*/
  52. // const p1 = new Promise((resolve, reject) => {
  53. const p1 = new MyPromise((resolve, reject) => {
  54. // setTimeout(() => {
  55. // resolve(1);
  56. reject(1);
  57. // }, 1000)
  58. })
  59. const p2 = p1.then((res) => {
  60. // console.log(res);
  61. return res + 1;
  62. }, err => {
  63. // console.log(err)
  64. return err + 2;
  65. })
  66. p2.then(res => {
  67. console.log(res,'success');
  68. }, err => {
  69. console.log(err,'error');
  70. })
  71. /*3 success*/

解析

返回的也是promise,then返回的是promise,new promise返回的也是promise,
1then返回new promise的p2,即使是第一次调用then时,也是返回一个新的promise对象,所以每次then都新建new Promise新建p2

  1. p2
  2. .then(res => {
  3. console.log(res, 'success');
  4. }, err => {
  5. console.log(err, 'error');
  6. })
  7. .then(res => {
  8. console.log(res, 'success');
  9. }, err => {
  10. console.log(err, 'error');
  11. })

image.png
第二次都是undefined

x = onFullFilled(this.value);的返回值是由

  1. const p2 = p1.then((res) => {
  2. // console.log(res);
  3. return res + 1;
  4. }, err => {
  5. // console.log(err)
  6. return err + 2;
  7. })

return出去的,x赋值为res+1,是then执行时,传入的回调函数,不立刻执行,之后执行的,是回调函数return的

x = onFullFilled(this.value);onFullFilled是形参,在这里面指代实参

  1. x=(res) => {
  2. // console.log(res);
  3. return res + 1;
  4. }

如果console,没有传值就是undefined

onFullFilled(this.value)中this.value相当于函数运行,传实参,res =this.value,传参并运行

为什么需要resolve(x)?
因为onFullFilled(this.value)需要新的this.value,每次链式操作拿到新的this.value,需要让它重新赋值,让this.value改变成回调函数return的值,在代码

  1. let resolve = (value) => {
  2. this.state = 'fullFilled';
  3. this.value = value;
  4. this.onFullFilledCallbacks.forEach(fn => fn());
  5. }

中,有改变value的值,并且如果一开始是reject,之后运行也需要改变之前的state的值,由失败变成功

处理new MyPromise

time 16m35s

  1. class MyPromise {
  2. constructor(executor) {
  3. this.state = 'pending';
  4. this.value = undefined;
  5. this.reason = undefined;
  6. this.onFullFilledCallbacks = [];
  7. this.onRejectedCallbacks = [];
  8. let resolve = (value) => {
  9. this.state = 'fullFilled';
  10. this.value = value;
  11. // this.onFullFilledCallbacks.forEach(fn => fn(this.value));
  12. this.onFullFilledCallbacks.forEach(fn => fn());
  13. }
  14. let reject = (reason) => {
  15. this.state = 'rejected';
  16. this.reason = reason;
  17. // this.onRejectedCallbacks.forEach(fn => fn(this.value));
  18. this.onRejectedCallbacks.forEach(fn => fn());
  19. }
  20. // executor(resolve, reject);
  21. try {
  22. executor(resolve, reject);
  23. } catch (err) {
  24. reject(err)
  25. }
  26. }
  27. then(onFullFilled, onRejected) {
  28. /*因为判断是同步执行的*/
  29. const p2 = new MyPromise((resolve, reject) => {
  30. let x;
  31. if (this.state === 'fullFilled') {
  32. /*让resolvePromise(p2, x, resolve, reject);之后再运行,如果p2声明赋值时*/
  33. setTimeout(() => {
  34. try {
  35. x = onFullFilled(this.value);
  36. // console.log(172, x);
  37. resolvePromise(p2, x, resolve, reject);
  38. } catch (err) {
  39. reject(err)
  40. }
  41. }, 0)
  42. /* x = onFullFilled(this.value);
  43. // console.log('165:'+x)
  44. // resolve(x);
  45. resolvePromise(p2, x, resolve, reject)*/
  46. }
  47. if (this.state === 'rejected') {
  48. setTimeout(() => {
  49. try {
  50. x = onRejected(this.reason);
  51. resolvePromise(p2, x, resolve, reject);
  52. } catch (err) {
  53. reject(err)
  54. }
  55. }, 0)
  56. }
  57. if (this.state === 'pending') {
  58. /* this.onFullFilledCallbacks.push(onFullFilled);
  59. this.onRejectedCallbacks.push(onRejected);*/
  60. this.onFullFilledCallbacks.push(() => {
  61. setTimeout(() => {
  62. try {
  63. x = onFullFilled(this.value);
  64. resolvePromise(p2, x, resolve, reject);
  65. } catch (err) {
  66. reject(err)
  67. }
  68. }, 0)
  69. });
  70. this.onRejectedCallbacks.push(() => {
  71. setTimeout(() => {
  72. try {
  73. x = onRejected(this.reason);
  74. resolvePromise(p2, x, resolve, reject);
  75. } catch (err) {
  76. reject(err)
  77. }
  78. }, 0)
  79. /* x = onRejected(this.reason);
  80. // resolve(x);
  81. resolvePromise(p2, x, resolve, reject);*/
  82. });
  83. }
  84. })
  85. return p2;
  86. }
  87. }
  88. function resolvePromise(p2, x, resolve, reject) {
  89. // console.log(192, p2, x, resolve, reject);
  90. // console.log(209,a);
  91. if (p2 === x) {
  92. reject(new TypeError('typeErr'));
  93. }
  94. /*x可以是个方法,再return出去一个值*/
  95. if ((typeof x === 'object' && x != null) || x === 'function') {
  96. try {
  97. /*thenable对象,这是处理return new Promise的情况*/
  98. let then = x.then;
  99. if (typeof then === 'function') {
  100. /* then.call(x是让then需要上下文,让then的上下文,变成x,变成
  101. * 返回的promise,相当于返回的promise.then*/
  102. then.call(x, y => {
  103. /*x.then值是一样的*/
  104. // x.then(y => {
  105. /*这时then独立调用指向window*/
  106. // then(y=>{
  107. console.log(250, y);
  108. resolve(y);
  109. }, r => {
  110. console.log(252, r);
  111. reject(r);
  112. })
  113. } else {
  114. resolve(x);
  115. }
  116. } catch (err) {
  117. reject(err);
  118. }
  119. } else {
  120. resolve(x);
  121. }
  122. }
  123. /*换成mypromise*/
  124. // const p1 = new Promise((resolve, reject) => {
  125. const p1 = new MyPromise((resolve, reject) => {
  126. // setTimeout(() => {
  127. resolve(1);
  128. // reject(1);
  129. // }, 1000)
  130. })
  131. const p2 = p1.then((res) => {
  132. // console.log(res);
  133. // return res + 1;
  134. /*返回值是一个Promise,想要拿到里面的reject,怎么拿到,需要通过得到它xx,
  135. * xx.then的方式得到10*/
  136. return new MyPromise((resolve, reject) => {
  137. reject(10);
  138. })
  139. }, err => {
  140. // console.log(err)
  141. return err + 2;
  142. })
  143. p2.then(res => {
  144. console.log(266, res, 'success');
  145. }, err => {
  146. console.log(268, err, 'error');
  147. })

time 34m06s

  1. function resolvePromise(p2, x, resolve, reject) {
  2. // console.log(192, p2, x, resolve, reject);
  3. // console.log(209,a);
  4. let called;
  5. if (p2 === x) {
  6. reject(new TypeError('typeErr'));
  7. }
  8. /*x可以是个方法,再return出去一个值*/
  9. if ((typeof x === 'object' && x != null) || x === 'function') {
  10. try {
  11. /*thenable对象,这是处理return new Promise的情况*/
  12. let then = x.then;
  13. if (typeof then === 'function') {
  14. /* then.call(x是让then需要上下文,让then的上下文,变成x,变成
  15. * 返回的promise,相当于返回的promise.then*/
  16. then.call(x, y => {
  17. /*x.then值是一样的*/
  18. // x.then(y => {
  19. /*这时then独立调用指向window*/
  20. // then(y=>{
  21. if (called) return;
  22. called = true;
  23. console.log(250, y);
  24. resolve(y);
  25. }, r => {
  26. if (called) return;
  27. called = true;
  28. console.log(252, r);
  29. reject(r);
  30. })
  31. } else {
  32. if (called) return;
  33. called = true;
  34. resolve(x);
  35. }
  36. } catch (err) {
  37. if (called) return;
  38. called = true;
  39. reject(err);
  40. }
  41. } else {
  42. /*这里不需要锁了*/
  43. resolve(x);
  44. }
  45. }

func

  1. const isFunction = (value) => typeof value === 'function';
  2. then(onFullFilled, onRejected) {
  3. onFullFilled = isFunction(onFullFilled) ? onFullFilled : data => data;
  4. onRejected = isFunction(onRejected) ? onRejected : err => {
  5. throw err;
  6. };

判断是否符合规范

time 37m38s
npm install promises-aplus-tests

promises-aplus-test app.js