promise-2

Promise API

  • promise 构造函数: promise(excutor){}

    • excutor函数:同步执行 (resolver, reject) => {}
    • resolver函数:函数内部定义成功时调用的函数 value => {}
    • reject函数:函数内部定义失败时调用的函数 reason => {}

    说明:excutor会在promise内部立即同步回调,异步操作代码在执行器中执行

  • Promise.prototype.then()方法:(onResolved, onRejected) => {}

    • onResolved函数:成功的回调函数 (value) => {}
    • onRejected函数:失败的回调函数 (reason) => {}

    说明:指定用于得到成功 value 的成功回调和用于得到失败 reason 的失败回调,返回一个新的promise对象

  • Promise.prototype.catch()方法:(onRejected) => {}

    • onRejected函数:失败的回调函数 (reason) => {}

    说明:then()的语法糖,相当于:then(undefined, onRejected)

  • Promise.resolve()方法:(value) => {}

    • value:成功的数据或promise对象

    说明:返回一个成功/失败的promise对象

  • Promise.reject()方法:(reason) => {}

    • reason:失败的数据或promise对象

    说明:返回一个成功/失败的promise对象

  • Promise.all()方法:(promises) => {}

    • promises:包含n个promises的数组

    说明:返回一个新的promise,只有所有的promise都成功才成功,有一个失败了就直接失败

  • Promise.race()方法:(promises) => {}

    • promises:包含n个promises的数组

    说明:返回一个新的promise,第一个完成的promise的结果状态就是最终的结果状态

以下这种情况,在回调中即执行了resolve,又执行了reject,这两个同时存在时,第二个没有效果。为什么呢?因为之前说过的,Promise 的状态只改变一次(pending => resolved / pending => rejected)

  • 基本语法

    new Promise((resolve, reject) => {
       setTimeout(() => {
          resolve('success data');
          // reject('failed data');
        }, 1000);
      }).then(
        value => {
          console.log('成功的回调函数 onResolved()1:', value);
        }
      ).catch(
        reason => {
          console.log('失败的毁掉函数 onRejected()1:',reason);
        }
      )
    
    // 产生一个成功值为1的promise对象
        const p1 = new Promise((resolve, rejected) => {
          resolve(1)
        });
        // 下面p2这个和上面p1效果一样,是上面的语法糖
        const p2 = Promise.resolve(2);
        const p3 = Promise.reject(3);
    
    // 得到结果
        p1.then(value => {console.log(value)});
        p2.then(value => {console.log(value)});
        // 失败的时候下面这两种方法一样
        p3.then(null, reason => {console.log(reason)});
        p3.catch(reason => {console.log(reason)})
    
  • Promise.all

    const p1 = new Promise((resolve, rejected) => {
      resolve(1)
     });
    const p2 = Promise.resolve(2);
    const p3 = Promise.reject(3);
    
    const pAll = Promise.all([p1, p2, p3])
     pAll.then(
       value => {
         console.log('all onResolved(): ', value);
       },
       reason => {
         console.log('all onRejected(): ', reason);
       }
     )
    

    上面的结果打印出来为3的原因:promise.all()方法的返回值中只要有一个失败了那么结果就是失败的。只有所有的都成功了才成功

    修改一下,去掉p3,将成功的value改为values👇:

    const p1 = new Promise((resolve, rejected) => {
      resolve(1)
     });
    const p2 = Promise.resolve(2);
    
    const pAll = Promise.all([p1, p2])
     pAll.then(
       values => {
         console.log('all onResolved(): ', values);
       },
       reason => {
         console.log('all onRejected(): ', reason);
       }
     )
    

    可以看到返回的结果是一个成功数据的数组

  • Promise.race() 【rece:竞赛。谁的速度快就输出谁的】


可以看到上面输出的是p1的值,因为我们这里只是输出数字,并没有太多的逻辑,所以基本就是按照数组里面的先后顺序来输出

如果想让失败的p3先输出的话就把p3放到最前面来

但是如果给它加上一些逻辑,比如说按照之前的顺序[p1, p2, p3],给p1加上计时器,然后就会看到结果不同了


这里可以看到虽然也是成功的回调,但是这次是p2的值了

所以说,最后的结果值取决于谁先完成

Promise 的几个关键问题

如何改变promise的状态?
  • resolve(value):如果当前是pending就会变为resolved
  • rejected(reason):如果当前是pending就会变为rejected
  • 抛出异常:如果当前是pending就会变成rejected
const p = new Promise((resolve, reject) => {
    throw new Error("err");
  })

  p.then(
    value => {
      console.log(value);
    },
    reason => {
      console.log(reason);
    }
  )
const p = new Promise((resolve, reject) => {
    // resolve(1);
    // reject(2);
    // 抛出异常,promise变为rejeted的失败状态,reason为抛出的error
    throw new Error("err");
    // 抛出异常,promise变为rejeted的失败状态,reason为抛出的3
    // 从语法上来说是可以抛出任何东西,但是真正在项目中抛的话就是error
    throw 3;
  })

  p.then(
    value => {
      console.log(value);
    },
    reason => {
      console.log(reason);
    }
  )
一个promise指定多个成功/失败回调函数,都会调用吗?

当promise改变对应状态时都会调用

const p = new Promise((resolve, reject) => {
    // resolve(1);
    // reject(2);
    throw new Error("err");
    throw 3;
  })

  p.then(
    value => {console.log(value);},
    reason => {console.log(reason);}
  )

  p.then(
    value => {console.log(value);},
    reason => {console.log(reason);}
  )
改变promise状态和指定回调函数谁先谁后?
  • 都有可能。正常情况下是先指定回调再改变状态,但也可以先改变状态再指定回调
  • 如何先改状态再指定回调
    • 在执行器中直接调用resolve()/reject()
    • 延迟更长时间再调用then()
  • 什么时候才能得到数据?
    • 如果先指定回调,那么当状态发生改变时,回调函数就会调用,得到数据
    • 如果先改变状态,那么当指定回调时,回调函数就会调用,得到数据
// 常规:先指定回调,后改变状态
    new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve(1); // 后改变状态(同时指定数据),异步执行回调函数
      }, 1000);
    }).then( // 先指定回调函数,保存当前指定的回调函数
      value => { console.log(value); },
      reason => { console.log(reason); }
    )


    // 先改状态,后指定回调函数
    new Promise((resolve, reject) => {
      resolve(1); // 先改变状态(同时指定数据)
    }).then( // 后指定回调函数,异步执行回调函数
      value2 => { console.log(value2); },
      reason2 => { console.log(reason2); }
    )


    // 还有一种方法,就是自己可以控制先后(先改状态,后指定回调函数)
    const p = new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve(1);
      }, 1000);
    })

    setTimeout(() => {
      p.then(
        value3 => { console.log(value3); },
        reason3 => { console.log(reason3); }
      )
    }, 1100);

promise 无论是成功还是失败的回调函数都是异步执行的

promise.then()返回的新的promise的状态由什么来决定?

  • 简单表达:由then()指定的回调函数执行的结果决定
  • 详细表达:
    • 如果抛出异常:新的promise变为rejected,reason变为抛出的异常
    • 如果返回的是非promise的任意值,新的promise变为resolve,value为返回的值
    • 如果返回的是另一个新的promise,此promise的结果就会变为新的promise的结果
new Promise((resolve, reject) => {
 resolve(1);
}).then(
  value => {console.log("onResolved1()", value);},
  reason => {console.log("onRejected1()", reason);}
).then(
  value => {console.log("onResolved2()", value);},
  reason => {console.log("onRejected2()", reason);}
)

说明:因为promise中执行的是resolve,所以then中执行的是value,因此第一个打印的是1;又因为第一个then里面没有return出一个值,所以第一个then执行完返回的值为undefined,那么第二个then执行的时候就相当于是undefined.then(),所以第二个then执行出来的值是undefined

new Promise((resolve, reject) => {
  resolve(1);
  // reject(2);
}).then(
  value => {
    console.log("onResolved1()", value);
     return 2;
    // 打印结果: 
    // onResolved1() 1   
    // onResolved2() 2   

     return Promise.resolve(3); 
    // 打印结果:  
    // onResolved1() 1   
    // onResolved2() 3

     return Promise.reject(4); 
    // 打印结果:    
    // onResolved1() 1   
    // onRejected2() 2

    },
  reason => {console.log("onRejected1()", reason);}
).then(
  value => {console.log("onResolved2()", value);},
  reason => {console.log("onRejected2()", reason);}
)

说明:第一个then成功,第二个then也就成功,成功返回的值和第一个一样。同理,第一个then失败,第二个then也就失败,失败返回的值和第一个一样

new Promise((resolve, reject) => {
 // resolve(1);
  reject(2);
}).then(
  value => {console.log("onResolved1()", value);},
  reason => {console.log("onRejected1()", reason);}
).then(
  value => {console.log("onResolved2()", value);},
  reason => {console.log("onRejected2()", reason);}
)
promise如何串联多个操作任务?
  • promise的then()返回一个新的promise,可以看成then()的链式调用
  • 通过then的链式调用串联多个同步/异步任务

要想在回调函数中执行异步任务,需要将异步任务封装进promise对象

new Promise((resolve, reject) => {
      setTimeout(() => {
        console.log("执行任务1(异步)");
        resolve(1);
      }, 1000);
    }).then(
      value => {
        console.log('任务1的结果:', value);
        console.log('执行任务2(同步)');
        return 2;
      }
    ).then(
      value => {
        console.log('任务2的结果:',value);

        return new Promise((resolve, reject) => {
          // 启动任务3(异步)
          setTimeout(() => {
            console.log('执行任务3(异步)');
            resolve(3);
          }, 1000);
        })
      }
    ).then(
      value => {
        console.log('任务3的结果:', value);
      }
    )

.then()返回的promise,由回调函数执行的结果决定,和是成功的回调或失败的回调没关系。比如之前的那个undefined

promise 异常传透
  • 当使用promise的then链式调用时,可以在最后指定失败的回调
  • 前面任何操作出了异常,都会传到最后失败的回调中处理

下面的代码中,执行了reject(1)之后,因为需要找失败对应的reason,如果默认只写了value而没有reason的话,就会一步一步往下走,直到catch()中执行返回打印结果onRejected() 1

这样一步一步往下走也就是传透的意思。而不是一下子就直接到catch()

但是默认不写reason的时候,其实是相当于给每个里面加了reason => {throw reason}这句或者reason => Promise.reject(reason)这句

new Promise((resolve, reject) => {
  reject(1);
 }).then(
   value => {
     console.log('onResolved1()', value);
     return 2;
   },
   // 默认不写相当于给这块加了下面这句
   // reason => {throw reason}
 ).then(
   value => {
     console.log('onResolved2()',value);
   },
   // 默认不写相当于给这块加了下面这句。与上面效果一样
   reason => Promise.reject(reason)
 ).then(
   value => {
     console.log('onResolved3()', value);
   },
   // 默认不写相当于给这块加了下面这句
   // reason => {throw reason}
 ).catch(reason => {
   console.log('onRejected()', reason);
 })

这个时候再给catch后面加一个.then()

new Promise((resolve, reject) => {
 reject(1);
}).then(
  value => {
    console.log('onResolved1()', value);
    return 2;
  },
  // 默认不写相当于给这块加了下面这句
  // reason => {throw reason}
).then(
  value => {
    console.log('onResolved2()',value);
  },
  // 默认不写相当于给这块加了下面这句。与上面效果一样
  reason => Promise.reject(reason)
).then(
  value => {
    console.log('onResolved3()', value);
  },
  // 默认不写相当于给这块加了下面这句
  // reason => {throw reason}
).catch(reason => {
  console.log('onRejected1()', reason);
}).then(
  value => {
    console.log('onResolved3()', value);
  },
  reason => {
    console.log('onRejected2()', reason);
  }
)

这块因为catch中返回的值是undefined(没有return值,但是没有抛出错误),所以最后的这个then里面走的是console.log('onResolved3()', value);

如果不想最后then里面返回的是undefined,那么就需要在catch中做处理👇

.catch(reason => {
  console.log('onRejected1()', reason);

  throw reason;
  // 或
  return Promise.reject(reason);

}).then(
  value => {
    console.log('onResolved3()', value);
  },
  reason => {
    console.log('onRejected2()', reason);
  }
)
中断promise链?
  • 当使用promise的then链式调用时,在中间中断,不会调用后面的回调函数
  • 放大:在回调函数中返回一个pending状态的promise对象
new Promise((resolve, reject) => {
  reject(1);
}).then(
  value => {
    console.log('onResolved1()', value);
    return 2;
  },
  // 默认不写相当于给这块加了下面这句
  // reason => {throw reason}
).then(
  value => {
    console.log('onResolved2()', value);
  },
  // 默认不写相当于给这块加了下面这句。与上面效果一样
  reason => Promise.reject(reason)
).then(
  value => {
    console.log('onResolved3()', value);
  },
  // 默认不写相当于给这块加了下面这句
  // reason => {throw reason}
).catch(reason => {
  console.log('onRejected1()', reason);
  // throw reason;
  // 或
  // return Promise.reject(reason);

  // 如果想中断不执行后面.then()中的方法
  // 返回一个pending状态的promise,中断promise链
  return new Promise(() => {})

}).then(
  value => {
    console.log('onResolved3()', value);
  },
  reason => {
    console.log('onRejected2()', reason);
  }
)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值