Promise

发布时间 2023-04-07 11:11:41作者: 饺子jo

Promise 及其应用

promise 与异步编程的关系

  • promise 是异步编程的一种解决方案,可以将异步对象和回调函数脱离开来,通过 then 方法在这个异步操作上面绑定回调函数。

  • 一个 Promise 有以下三个状态

    • pending:操作正在进行
    • fulfilled:操作成功
    • rejected:操作失败
  • 语法

    var promise=new Promise((resolve,reject)=>{
    //....一些异步操作
    	if(/*异步操作成功*/){
    		resolve(value);
    	}else{
    		reject(error);
    	}
    });
    promise.then((value)=>{
    	//fulfilled
    },(errror)=>{
    	//rejected
    })
    //一般rejected状态使用catch方法来抛出错误,而不在then方法中。
    /*.catch((error)=>{
    console.log(error);
    })*/
    

promise 的作用与用法

  • 简单使用

    function timeout(ms) {
      return new Promise((resolve, reject) => {
        setTimeout(resolve, ms, "done");
      });
    }
    
    timeout(2000).then((value) => {
      console.log(value); //done
    });
    

    2000 过后,pending->fulfilled,调用 then 方法,'done'作为 resolve 返回值传递给 then,即 value。

  • 注意点

    1. Promise 对象在创建后立即执行,then 方法指定的回调函数,将在当前脚本所有的同步任务执行完后才会执行。

      let promise = new Promise((resolve, reject) => {
        console.log("Promise1");
        resolve();
        console.log("Promise2");
      });
      
      promise.then(() => {
        console.log("resolved.");
      });
      
      console.log("Hi!");
      
      // Promise1
      // Promise2
      // Hi!
      // resolved
      

静态方法

iterable:可迭代对象

  • Promise.all(iterable)
    这个方法返回一个新的 promise 对象,等到所有的 promise 对象都成功或有任意一个 promise 失败。

    如果所有的 promise 都成功了,它会把一个包含 iterable 里所有 promise 返回值的数组作为成功回调的返回值。顺序跟 iterable 的顺序保持一致。

    一旦有任意一个 iterable 里面的 promise 对象失败则立即以该 promise 对象失败的理由来拒绝这个新的 promise。

const promise1 = Promise.resolve(3);
const promise2 = 42;
const promise3 = new Promise((resolve, reject) => {
  setTimeout(resolve, 100, "foo");
});

Promise.all([promise1, promise2, promise3]).then((values) => {
  console.log(values);
});
// Expected output: Array [3, 42, "foo"]
  • Promise.allSettled(iterable)

    等到所有 promise 都已敲定(每个 promise 都已兑现或已拒绝)。

    返回一个 promise,该 promise 在所有 promise 都敲定后完成,并兑现一个对象数组,其中的对象对应每个 promise 的结果。

    const promise1 = Promise.resolve(3);
    const promise2 = new Promise((resolve, reject) =>
      setTimeout(reject, 100, "foo")
    );
    const promises = [promise1, promise2];
    
    Promise.allSettled(promises).then((results) =>
      results.forEach((result) => console.log(result.status))
    );
    
    // Expected output:
    // "fulfilled"
    // "rejected"
    
  • Promise.any(iterable)

    接收一个 promise 对象的集合,当其中的任意一个 promise 成功,就返回那个成功的 promise 的值。

    const pErr = new Promise((resolve, reject) => {
      reject("总是失败");
    });
    
    const pSlow = new Promise((resolve, reject) => {
      setTimeout(resolve, 500, "最终完成");
    });
    
    const pFast = new Promise((resolve, reject) => {
      setTimeout(resolve, 100, "很快完成");
    });
    
    Promise.any([pErr, pSlow, pFast]).then((value) => {
      console.log(value);
      // pFast fulfils first
    });
    // 期望输出:"很快完成"
    
  • Promise.race(iterable)

    等到任意一个 promise 的状态变为已敲定。

    当 iterable 参数里的任意一个子 promise 成功或失败后,父 promise 马上也会用子 promise 的成功返回值或失败详情作为参数调用父 promise 绑定的相应处理函数,并返回该 promise 对象。

    const promise1 = new Promise((resolve, reject) => {
      setTimeout(resolve, 500, "one");
    });
    
    const promise2 = new Promise((resolve, reject) => {
      setTimeout(resolve, 100, "two");
    });
    
    Promise.race([promise1, promise2]).then((value) => {
      console.log(value);
      // Both resolve, but promise2 is faster
    });
    // Expected output: "two"
    
  • Promise.reject(reason)
    返回一个状态为已拒绝的 Promise 对象,并将给定的失败信息传递给对应的处理函数。

function resolved(result) {
  console.log("Resolved");
}

function rejected(result) {
  console.error(result);
}

Promise.reject(new Error("fail")).then(resolved, rejected);
// Expected output: Error: fail
  • Promise.resolve(iterable)
    返回一个状态由给定 value 决定的 Promise 对象。如果该值是 thenable(即,带有 then 方法的对象),返回的 Promise 对象的最终状态由 then 方法执行结果决定;否则,返回的 Promise 对象状态为已兑现,并且将该 value 传递给对应的 then 方法。

通常而言,如果你不知道一个值是否是 promise 对象,使用 Promise.resolve(value) 来返回一个 Promise 对象,这样就能将该 value 以 promise 对象形式使用。

const promise1 = Promise.resolve(123);

promise1.then((value) => {
  console.log(value);
  // Expected output: 123
});

实例方法

  • Promise.prototype.catch()

    为 promise 添加一个被拒绝状态的回调函数,并返回一个新的 promise,若回调函数被调用,则兑现其返回值,否则兑现原来的 promise 兑现的值。

    const promise1 = new Promise((resolve, reject) => {
      throw new Error("Uh-oh!");
    });
    
    promise1.catch((error) => {
      console.error(error);
    });
    // Expected output: Error: Uh-oh!
    
  • Promise.prototype.then()

    为 promise 添加被兑现和被拒绝状态的回调函数,其以回调函数的返回值兑现 promise。若不处理已兑现或者已拒绝状态(例如,onFulfilledonRejected 不是一个函数),则返回 promise 被敲定时的值。

    const promise1 = new Promise((resolve, reject) => {
      resolve("Success!");
    });
    
    promise1.then((value) => {
      console.log(value);
      // Expected output: "Success!"
    });
    
  • Promise.prototype.finally()

    为 promise 添加一个回调函数,并返回一个新的 promise。这个新的 promise 将在原 promise 被兑现时兑现。而传入的回调函数将在原 promise 被敲定(无论被兑现还是被拒绝)时被调用。

    在 promise 结束时,无论结果是 fulfilled 或者是 rejected,都会执行指定的回调函数。这为在 Promise 是否成功完成后都需要执行的代码提供了一种方式。这避免了同样的语句需要在 then()catch() 中各写一次的情况。

实际环境应用

示例:
本例展示了 Promise 的一些机制。testPromise() 方法在每次点击