1. Promise的构造函数是同步执行,Promise.then中的函数是异步执行。

**

  1. const promise = new Promise((resolve, reject)=>{
  2. console.log(1);
  3. resolve();
  4. console.log(2);
  5. });
  6. promise.then(()=>{
  7. console.log(4);
  8. });
  9. console.log(5);

image.png

  1. 构造函数中的 resolve 或 reject 只有第一次执行有效,多次调用没有任何作用。promise 状态一旦改变则不能再变。 promise 有 3 种状 态: pending、fulfilled 或 rejected。 状态改变只能是 pending->fulfilled 或者 pending-> rejected,状态一旦改变则不能再变。 ```javascript

const promise = new Promise((resolve, reject) => { resolve(‘success1’) reject(‘error’) resolve(‘success2’) });

promise .then((res) => { console.log(‘then: ‘, res) }) .catch((err) => { console.log(‘catch: ‘, err) })

  1. ![image.png](https://cdn.nlark.com/yuque/0/2020/png/154143/1607679818698-47eafb72-558f-48a9-9ade-0daf3632dab6.png#align=left&display=inline&height=514&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1028&originWidth=1786&size=151046&status=done&style=none&width=893)<br />![image.png](https://cdn.nlark.com/yuque/0/2020/png/154143/1607679870700-5417b21f-8b39-4297-8569-b520f05b41ff.png#align=left&display=inline&height=497&margin=%5Bobject%20Object%5D&name=image.png&originHeight=994&originWidth=1858&size=149610&status=done&style=none&width=929)
  2. 3. **promise .then 或者 .catch 可以被调用多次,但这里 Promise 构造函数只执行一次。或者说 promise 内部状态一经改变,并且有了一个值,那么后续每次调用 .then 或者 .catch 都会直接拿到该值。**
  3. **
  4. ```javascript
  5. const promise = new Promise((resolve, reject) => {
  6. setTimeout(() => {
  7. console.log('once')
  8. resolve('success')
  9. }, 1000)
  10. })
  11. const start = Date.now()
  12. promise.then((res) => {
  13. console.log(res, Date.now() - start)
  14. })
  15. promise.then((res) => {
  16. console.log(res, Date.now() - start)
  17. })

image.png


  1. console.log('start');
  2. new Promise(function (resolve, reject) {
  3. setTimeout(function () { //定时器模拟异步
  4. resolve('hello'); //修改promise状态调用then中的第一个函数
  5. }, 2000);
  6. }).then((value) => {
  7. console.log(value); //接收resolve传来的值
  8. return new Promise(function (resolve) { //该then()返回一个新的promise实例,后面可以继续接then
  9. setTimeout(function () {
  10. resolve('world'); //修改新promise的状态,去调用then
  11. }, 3000)
  12. })
  13. }).then((value) => {
  14. console.log(value);
  15. })

输出结果: 立即输出 start 两秒输出 hello 再三秒 world
image.png

  1. 上面我们在 then() 函数中返回的是一个新的promise,如果返回的不是一个新的promise会怎样呢?依然是上面的代码,稍作修改。 ```javascript

console.log(‘start’); new Promise(function (resolve, reject) { setTimeout(function () { resolve(‘hello’); }, 2000); }).then((value) => { console.log(value); (function () { return new Promise(function (resolve) { setTimeout(function () { resolve(‘world’); }, 3000) }) })(); return false; }).then((value) => { console.log(value); })

  1. 结果: 立即输出 start 两秒输出 hello 三秒输出 false<br />![image.png](https://cdn.nlark.com/yuque/0/2020/png/154143/1607680579088-8d2c6ed9-57c4-4986-81ee-d4b0ba225f38.png#align=left&display=inline&height=635&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1270&originWidth=1816&size=204925&status=done&style=none&width=908)<br />**根据上面的运行结果来看,如果在一个then()中没有返回一个新的promise,则return 什么下一个then就接受什么,在上面的实例代码中return的是false,下一个 then中接受到的value就是false,如果then中没有return,则默认return的是 undefined.**
  2. 6. **then()中包含.then()的嵌套情况 then()的嵌套会先将内部的then()执行完毕再继续执行外部的then();在多个then嵌套时建议将其展开,将then()放在同一级,这样代码更清晰。**
  3. ```javascript
  4. console.log('start');
  5. new Promise((resolve, reject) => {
  6. setTimeout(function () {
  7. console.log('step');
  8. resolve(110);
  9. }, 1000)
  10. })
  11. .then((value) => {
  12. return new Promise((resolve, reject) => {
  13. setTimeout(function () {
  14. console.log('step1');
  15. resolve(value);
  16. }, 1000)
  17. })
  18. .then((value) => {
  19. console.log('step 1-1');
  20. return value;
  21. })
  22. .then((value) => {
  23. console.log('step 1-2');
  24. return value;
  25. })
  26. })
  27. .then((value) => {
  28. console.log(value);
  29. console.log('step 2');
  30. })
  31. /* start step step1 step 1-1 step 1-2 110 step 2 */
  32. //展开之后的代码
  33. console.log('start');
  34. new Promise((resolve, reject) => {
  35. setTimeout(function () {
  36. console.log('step');
  37. resolve(110);
  38. }, 1000)
  39. })
  40. .then((value) => {
  41. return new Promise((resolve, reject) => {
  42. setTimeout(function () {
  43. console.log('step1');
  44. resolve(value);
  45. }, 1000)
  46. })
  47. })
  48. .then((value) => {
  49. console.log('step 1-1');
  50. return value;
  51. })
  52. .then((value) => {
  53. console.log('step 1-2');
  54. return value;
  55. })
  56. .then((value) => {
  57. console.log(value);
  58. console.log('step 2');
  59. })

image.png

  1. catch和then的连用 如果每一步都有可能出现错误,那么就可能出现catch后面接上then的情况。 ```javascript new Promise((resolve, reject) => { resolve(); }) .then(value => { console.log(‘done 1’); throw new Error(‘done 1 error’); }) .catch(err => { console.log(‘错误信息1:’ + err); }) .then(value => { console.log(‘done 2’); }) .catch(err => { console.log(‘错误信息2:’ + err); }) // done 1 错误信息1:Error: done 1 error done 2 说明catch后面会继续执行then,catch返回的也是一个promise实例 ß new Promise((resolve, reject) => { resolve(); }) .then(value => { console.log(‘done 1’); throw new Error(‘done 1 error’); }) .catch(err => { console.log(‘错误信息1:’ + err); throw new Error(‘catch error’); }) .then(value => { console.log(‘done 2’); }) .catch(err => { console.log(‘错误信息2:’ + err); }) // done 1 错误信息1:Error: done 1 error 错误信息2:Error: catch error 如果在catch中也抛出了错误,则后面的then的第一个函数不会执行,因为返回的 promise状态已经为rejected了
  1. ![image.png](https://cdn.nlark.com/yuque/0/2020/png/154143/1607681109057-98a08a44-38be-4f51-97a3-5eec23b25a0a.png#align=left&display=inline&height=239&margin=%5Bobject%20Object%5D&name=image.png&originHeight=478&originWidth=1862&size=82507&status=done&style=none&width=931)
  2. 8. **Promise.all() 将多个Promise批量执行,所有的Promise都完毕之后返回一个新的Promise**
  3. ```javascript
  4. // 1、接收一个数组作为参数
  5. // 2、数组中可以是Promise实例,也可以是别的值,只有Promise会等待状态的改变
  6. // 3、所有子Promise完成,则该Promise完成,并且返回值是参数数组中所有Promise实例的结果组成的数组
  7. // 4、有任何一个Promise失败,则该Promise失败,返回值是第一个失败的Promise的结果
  8. console.log('here we go');
  9. Promise.all([1, 2, 3])
  10. .then(all => {
  11. console.log('1: ' + all);
  12. return Promise.all([function () {
  13. console.log('ooxx');
  14. }, 'xxoo', false])
  15. })
  16. .then(all => {
  17. console.log('2: ' + all);
  18. let p1 = new Promise(resolve => {
  19. setTimeout(function () {
  20. resolve('I\'m p1');
  21. }, 1500)
  22. });
  23. let p2 = new Promise(resolve => {
  24. setTimeout(function () {
  25. resolve('I\'m p2');
  26. }, 2000)
  27. });
  28. return Promise.all([p1, p2]);
  29. })
  30. .then(all => {
  31. console.log('3: ' + all);
  32. let p1 = new Promise((resolve, reject) => {
  33. setTimeout(function () {
  34. resolve('P1');
  35. }, 1000)
  36. })
  37. let p2 = new Promise((resolve, reject) => {
  38. setTimeout(function () {
  39. reject('P2');
  40. }, 3000)
  41. })
  42. let p3 = new Promise((resolve, reject) => {
  43. setTimeout(function () {
  44. reject('P3');
  45. }, 2000)
  46. })
  47. return Promise.all([p1, p2, p3]);
  48. })
  49. .then(all => {
  50. console.log('all: ' + all);
  51. })
  52. .catch(err => {
  53. console.log('Catch:' + err);
  54. })
  55. // here we go 1: 1,2,3 2: function(){ console.log('ooxx'); },xxoo,false 3: I'm p1,I'm p2 Catch:P3 证明了上面的四点。

image.png

  1. Promise.race() 和Promise.all()差不多,区别就是传入的数组中有一个Promise完成了则整个Promise完成了。
  1. let p1 = new Promise(resolve => {
  2. setTimeout(function () {
  3. resolve('p1');
  4. }, 10000);
  5. })
  6. let p2 = new Promise(resolve => {
  7. setTimeout(function () {
  8. resolve('p2');
  9. }, 1000);
  10. })
  11. Promise.race([p1, p2])
  12. .then((value) => {
  13. console.log(value);
  14. })
  15. // p1 1s之后输出 。。 等待十秒后代码才算执行完毕

image.png

参考文档

https://yuanfentiank789.github.io/2019/11/07/promise%E6%89%A7%E8%A1%8C%E9%A1%BA%E5%BA%8F%E6%80%BB%E7%BB%93/