js异步之Promise使用

Promise是异步编程的一种解决方案,是一个对象,可以获取异步操作的消息,大大改善了异步编程的困难,避免了回调地狱,比传统的解决方案回调函数和事件更合理和更强大。

从语法上讲,Promise是一个对象,它可以获取异步操作的消息。提供了一个统一的API,各种异步操作都可以用同样的方法进行处理

 

Promise的实例有三个状态:Pending(进行中)、Resolved(已完成)、Rejected(已拒绝)

Promise的实例有两个过程:
pending > fulfiled :Resolved
pending > rejected :Rejected

 

创建Promise对象

  const p1 = new Promise((resolve) => {
    setTimeout(() => {
      resolve("a");
    }, 2000);
  });
  const p2 = new Promise((resolve, reject) => {
    setTimeout(() => {
      reject("b");
    }, 1000);
  });

then、catch、finally方法

then 方法:可以接收两个回调函数作为参数,第一个回调函数是Promise对象的状态改变为 resoved 是调用,第二个回调函数是 Promise 对象的状态变为 rejected 时调用。

catch方法:在执行resolve回调函数时,如果出错,抛出异常,不会停止运行,而是进入catch 方法中。若未定义reject回调函数则reject时会被当成error处理

finally方法:用于指定不管 Promise 对象最后状态如何,都会执行的操作。

resolve

  p1.then(
    (res_resolve) => {
      console.log("resolved:", res_resolve); //resolved: a
    },
    (res_reject) => {
      console.log("rejected:", res_reject);
    }
  )
    .catch((res) => {
      console.log("error:", res);
    })
    .finally(() => {
      console.log("done"); //done
    });

reject

  p2.then(
    (res_resolve) => {
      console.log("resolved:", res_resolve);
    },
    (res_reject) => {
      console.log("rejected:", res_reject); //rejected: b
    }
  ).catch((res) => {
    console.log("error:", res);
  });

  p2.then((res_resolve) => {
    console.log("resolved:", res_resolve);
  }).catch((res) => {
    console.log("error:", res); //error: b  若未定义reject回调则reject时会被当成error处理
  });

链式调用

 p1.then(
    (res_resolve) => {
      console.log("p1 resolved:", res_resolve); //p1 resolved: a
      return p2;
    },
    (res_reject) => {
      console.log("p1 rejected:", res_reject);
    }
  )
    .catch((res) => {
      console.log("p1 error:", res); //p1 error: b
    })
    .then(
      (res_resolve) => {
        console.log("p2 resolved:", res_resolve); //p2 resolved: undefined
      },
      (res_reject) => {
        console.log("p2 rejected:", res_reject);
      }
    )
    .catch((res) => {
      console.log("p2 error:", res);
    });

似乎并不是想要的结果,修改如下: 


  p1.then(
    (res_resolve) => {
      console.log("p1 resolved:", res_resolve); //p1 resolved: a
      return p2;
    },
    (res_reject) => {
      console.log("p1 rejected:", res_reject);
    }
  )
    .then(
      (res_resolve) => {
        console.log("p2 resolved:", res_resolve);
      },
      (res_reject) => {
        console.log("p2 rejected:", res_reject); //p2 rejected: b
      }
    )
    .catch((res) => {
      console.log("p2 error:", res);
    });

  p1.then((res) => {
    console.log("p1 resolved:", res); //p1 resolved: a
    return p2;
  })
    .then((res) => {
      console.log("p2 resolved:", res);
    })
    .catch((res) => {
      console.log("p2 error:", res); //p2 error: b
    });

async函数

async function func(params) {
    return params;
  }

  func("a")
    .then((res) => {
      console.log(res);//a
      return func("b");
    })
    .then((res) => {
      console.log(res);//b
    });

 Promise.all方法

只有等所有请求都结束才会有结果,都成功才会执行then,返回结果按照参数顺序
 const list1 = [
    new Promise((resolve) => {
      setTimeout(() => {
        resolve("list1 resolve index:1");
      }, 2000);
    }),
    new Promise((resolve) => {
      setTimeout(() => {
        resolve("list1 resolve index:2");
      }, 1000);
    }),
  ];
  const list2 = [
    new Promise((resolve) => {
      setTimeout(() => {
        resolve("list2 resolve index:1");
      }, 3000);
    }),
    new Promise((resolve, reject) => {
      setTimeout(() => {
        reject("list2 reject index:2");
      }, 2000);
    }),
    new Promise((resolve) => {
      setTimeout(() => {
        resolve("list2 resolve index:3");
      }, 1000);
    }),
  ];
  const list3 = [
    new Promise((resolve, reject) => reject("list3 reject index:1")),
    new Promise((resolve, reject) => reject("list3 reject index:2")),
    new Promise((resolve, reject) => reject("list3 reject index:3")),
  ];


  Promise.all(list1).then((res) => {
    console.log(res); //['list1 resolve index:1', 'list1 resolve index:2']
  });
  Promise.all(list2)
    .then((res) => {
      console.log(res);
    })
    .catch((res) => {
      console.log(res); //list2 reject index:2
    });

 Promise.any方法

只要有一个成功,就会执行then,只有当所有的promise都失败,才算失败
 Promise.any(list1).then((res) => {
    console.log(res); // list1 resolve index:2
  });
  Promise.any(list2)
    .then((res) => {
      console.log(res); //list2 resolve index:3
    })
    .catch((res) => {
      console.log("error:", res);
    });
  Promise.any(list3)
    .then((res) => {
      console.log(res);
    })
    .catch((res) => {
      console.log("error:", res); //error: AggregateError: All promises were rejected
    });

 Promise.race方法

只要最快的那个,不管结果
  Promise.race(list1).then((res) => {
    console.log(res); // list1 resolve index:2
  });
  Promise.race(list2)
    .then((res) => {
      console.log(res); //list2 resolve index:3
    })
    .catch((res) => {
      console.log("error:", res);
    });
  Promise.race(list3)
    .then((res) => {
      console.log(res);
    })
    .catch((res) => {
      console.log("error:", res); //error: list3 reject index:1
    });
超时处理
  const timeoutPromise = new Promise((resolve, reject) => {
    setTimeout(() => reject(new Error("Request timeout")), 500);
  });
  Promise.race([p1, timeoutPromise])
    .then((res) => console.log(res))
    .catch((res) => console.log(res)); // Error: Request timeout

Promise.allSettled

等所有请求结束后,它不会执行.catch,只会执行.then
  Promise.allSettled(list1).then((res) => {
    console.log(res); // [{status: 'fulfilled', value: 'list1 resolve index:1'},{status: 'fulfilled', value: 'list1 resolve index:2'}]
  });
  Promise.allSettled(list2)
    .then((res) => {
      console.log(res); //[{status: 'fulfilled', value: 'list2 resolve index:1'},{status: 'rejected', reason: 'list2 reject index:2'},{status: 'fulfilled', value: 'list2 resolve index:3'}]
    })
    .catch((res) => {
      console.log("error:", res);
    });
  Promise.allSettled(list3)
    .then((res) => {
      console.log(res); //[{status: 'rejected', reason: 'list3 reject index:1'},{status: 'rejected', reason: 'list3 reject index:2'},{status: 'rejected', reason: 'list3 reject index:3'}]
    })
    .catch((res) => {
      console.log("error:", res);
    });

 

posted @ 2024-08-15 11:26  carol2014  阅读(1)  评论(0编辑  收藏  举报