8.js 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. //! Promise对象
  2. // Promise 就是 “承诺” 的意思。代表未来某个时间要发生的事。它的出现是为了更好的处理异步任务。
  3. //! 1. 同步与异步
  4. var a = 10;
  5. console.log(a);
  6. var b = 20;
  7. console.log(b);
  8. //COMMENT 上面代码 都属于 同步代码 即我们所说的同步任务
  9. //! 同步的特点是,代码 是 自顶向下 一行一行的执行,只有当前行有返回值或者运算完成后,才会执行下一行代码。
  10. var c = 10;
  11. console.log(c);
  12. // 定时器中回调函数 就是 异步代码 即我们所说的异步任务
  13. setTimeout(() => {
  14. console.log('timer');
  15. }, 1000);
  16. console.log('end');
  17. // 上面代码 输出的顺序为 : 10,'end', 'timer'
  18. //! 上面代码 中 包含异步任务,特点是 异步任务不会阻塞同步任务的执行,如果下面还有同步任务,继续执行。也就说 同步任务 此时的执行优先级高于 异步任务。
  19. //! 小结:在JavaScript中,常见的异步任务:
  20. /**
  21. * 1. 事件处理函数
  22. * 2. 定时器 setTimeout 和 setInterval
  23. * 3. 网络请求Ajax
  24. * 4. Promise对象
  25. * */
  26. //! 2. 创建Promise对象
  27. // 语法 const promise = new Promise(executor)
  28. const promise = new Promise((resolve, reject) => {
  29. // executor 是同步的回调函数,当new Promise的时候executor会立即执行。
  30. // 这里就是 要编写的异步任务
  31. setTimeout(() => {
  32. // 1.5s后 该异步任务会执行
  33. // 执行后,要给Promise对象设置状态(成功或者失败),以及异步任务的结果
  34. // 在 executor中 会接收两个参数 resolve 和 reject
  35. // resolve(value) 将Promise对象的状态设置为成功的(fulfilled),并将参数value设置为成功的结果值
  36. // reject(reason) 将Promise对象的状态设置为失败的(rejected),并将参数reason设置为失败的原因
  37. let n = Math.random(); // 创建一个随件数
  38. // 如果n大于 0.5 那么成功,结果值 为 n
  39. if (n > 0.5) {
  40. resolve(n);
  41. reject(); // 这里并不会 将promise状态修改为 失败的。由于上面已经调用resolve了 此reject会被忽略
  42. } else {
  43. // 否则 失败,失败的原因 为 '你太小了'
  44. reject('你太小了');
  45. }
  46. }, 1500);
  47. });
  48. console.log(promise);
  49. //! 3. 获取Promise对象结果
  50. // promise.then(
  51. // (value) => {
  52. // console.log('你成功了,值为:', value);
  53. // },
  54. // (reason) => {
  55. // console.log('你拜拜了,因为:', reason);
  56. // }
  57. // );
  58. //! promise对象的then方法会返回一个新的Promise对象
  59. //! 4. Promise对象 还有一个 专门用于处理失败的方法 catch
  60. promise
  61. .then((value) => {
  62. console.log('你成功了,值为:', value);
  63. })
  64. .catch((reason) => {
  65. console.log('你拜拜了,因为:', reason);
  66. });
  67. //COMMENT 上面代码 由于then方法没有传入失败的处理函数,因此一旦promise失败了,就会将状态和结果都交给then返回的新Promise对象上,然后就可以通过新Promise对象调用catch方法去处理失败的情况了。
  68. //! 5 静态方法 就是 构造函数的方法 Promise.resolve(value)
  69. // 直接返回一个Promise对象,通过状态为 成功的,以及成功的值为value参数。value可以为任何值。
  70. console.log(Promise.resolve(1));
  71. //! 6 静态方法 就是 构造函数的方法 Promise.reject(reason)
  72. // 直接返回一个Promise对象,通过状态为 失败的,以及失败的原因为reason参数。reason可以为任何值。
  73. console.log(Promise.reject('我就失败了咋地!!!'));
  74. //! 6 回调地狱
  75. // 举栗子:
  76. // 假如 有3个定时器:A - 1s后执行,B - 3s后执行,C - 2s后执行,但是要求 A 执行后 在执行B,B执行后 在执行C。
  77. setTimeout(() => {
  78. console.log('任务A完事了');
  79. // 开启任务B
  80. setTimeout(() => {
  81. console.log('任务B完事了');
  82. setTimeout(() => {
  83. console.log('任务C完事了');
  84. }, 2000);
  85. }, 3000);
  86. }, 1000);
  87. //! 在上述代码中的实现 你会发现 setTimeout中的回调函数 一直在嵌套下去,一旦这种异步任务 需要有序的、像同步任务那样一个一个的执行,就会产生一种现象--回调地狱。影响代码的可读性,也就说维护这样的代码会变得困难。
  88. //! 6.1 使用Promsie对象来解决
  89. function taskA() {
  90. return new Promise((resolve) => {
  91. setTimeout(() => {
  92. resolve('任务A完事了');
  93. }, 1000);
  94. });
  95. }
  96. function takB() {
  97. return new Promise((resolve) => {
  98. setTimeout(() => {
  99. resolve('任务B完事了');
  100. }, 3000);
  101. });
  102. }
  103. function taskC() {
  104. return new Promise((resolve) => {
  105. setTimeout(() => {
  106. resolve('任务C完事了');
  107. }, 2000);
  108. });
  109. }
  110. taskA()
  111. .then((v) => {
  112. console.log(v);
  113. return taskB();
  114. })
  115. .then((v) => {
  116. console.log(v);
  117. return taskC();
  118. })
  119. .then((v) => {
  120. console.log(v);
  121. });
  122. //! 由于AP.then方法中的回调函数 指定了 返回值 为 一个新的Promise对象BP,因此 AP.then方法它自己返回的Promise对象的状态就和BP关联,同理后面也是一样的道理。
  123. var p1 = Promise.resolve(1).then((v) => {
  124. console.log(`output->v`, v);
  125. });
  126. console.log(p1); // p1 就是 then方法返回值Promise对象
  127. var p2 = Promise.reject(1).catch((v) => {
  128. console.log(`output->v`, v);
  129. });
  130. console.log(p2); // p2 就是 catch方法返回值Promise对象