欢迎光临散文网 会员登陆 & 注册

js基础之Promise详解

2023-05-25 11:52 作者:限量版范儿  | 我要投稿

1. 是什么

Promise是一种异步编程的解决方案,用于处理异步操作并返回结果。
主要作用是解决回调函数嵌套(回调地狱)的问题,使异步操作更加清晰、易于理解和维护。

2. 怎么用

Promise有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。当一个Promise被创建时,它的状态为pending。当异步操作完成并成功时,Promise的状态会变为fulfilled,并返回一个结果。当异步操作失败时,Promise的状态会变为rejected,并返回一个错误信息。

基本语法

// 创建一个promise let promise = new Promise(function(resolve, reject) {// 异步操作if (异步操作成功) {resolve(value); // 将异步操作的结果传递给Promise对象,状态变为fulfilled} else {reject(error); // 将异步操作的错误信息传递给Promise对象,状态变为rejected} });promise.then(function(result) {// 异步操作成功时的处理代码 }).catch(function(error) {// 异步操作失败时的处理代码 });

常用方法

1.then

then中一般传入两个参数(函数),第一个对应resolve成功的回调,第二个对应reject失败的回调,如下

function onResolved(res) {  console.log("resolved-" + res); // resolved-成功了 } function onRejected(err) {  console.log("rejected-" + err); // rejected-失败了 } new Promise((resolve, reject) => {  resolve('成功了');// reject('失败了') }).then(onResolved, onRejected);

then的第二个参数就等同于catch方法,但是需要注意

  • Promise内部报错,reject抛出错误后,then的第二个参数和catch方法都存在的情况下,只有then的第二个参数能捕获到,如果then的第二个参数不存在,catch方法会捕捉到

  • catch不仅捕捉promise中抛出的错误,还会捕捉前面then中的错误

2.catch

捕捉promise错误函数,和then的第二个参数(函数)作用一样,处理错误,由于Promise抛出错误具有冒泡性质,能够不断传递,会传到catch中,所以一般来说所有错误处理放在catch中,then中只处理成功的,同时catch还会捕捉then中第一个参数(函数)抛出的异常

new Promise((resolve, reject) => {  reject(); }).catch((err)=> {  console.log(err) });

3.finally

  • finally 方法没有参数,也不会改变 Promise 的状态,它只是在 Promise 结束时提供了一个通知机制,让我们可以在 Promise 结束后执行一些清理工作(比如操作文件的时候关闭文件流)。

  • Promise对象的finally()方法用于在Promise成功或拒绝时使用

  • 不管promise最后的状态,在执行完then或catch指定的回调函数以后,都会执行finally方法指定的回调函数,它可以防止Promise的then()和catch()方法中的代码重复。

// 栗子1 function onFinally() {  console.log('结束'); } new Promise((resolve, reject) => {}).finally(onFinally); // 栗子2 let promise = new Promise((resolve,reject) => {    resolve('resolve') }) promise.then((res) => {    console.log(res) }).catch((err) => {    console.log(err) }).finally(()=> {    console.log('this finally') }) // resolve // this finally

4.all

接受一个具有Iterable接口的类型,如数组,Map,Set,传入多个promise,
每一个promise执行成功resolve,最后才执行成功(返回一个Promise实例),进入then,否则失败进入catch

function p1() {  var promise1 = new Promise(function (resolve, reject) {      console.log("p1的第一条输出语句");      resolve("p1完成");  });  return promise1; } function p2() {  var promise2 = new Promise(function (resolve, reject) {      console.log("p2的第一条输出语句");      setTimeout(() => {        console.log("p2的第二条输出语句");        resolve("p2完成");}, 2000);      });return promise2; } function p3() {  var promise3 = new Promise(function (resolve, reject) {      console.log("p3的第一条输出语句");      resolve("p3完成");  });  return promise3; } Promise.all([p1(), p2(), p3()]).then(function (data) {  console.log(data); });// 输出 // p1的第一条输出语句; // p2的第一条输出语句; // p3的第一条输出语句; // p2的第二条输出语句[("p1完成", "p2完成", "p3完成")]; var p1 = new Promise((resolve, reject) => {  setTimeout(resolve, 1000, 'one'); }); var p2 = new Promise((resolve, reject) => {  setTimeout(resolve, 2000, 'two'); }); var p3 = new Promise((resolve, reject) => {  setTimeout(resolve, 3000, 'three'); }); var p4 = new Promise((resolve, reject) => {  setTimeout(resolve, 4000, 'four'); }); var p5 = new Promise((resolve, reject) => {  reject('reject');// setTimeout(resolve, 5000, 'five'); }); Promise.all([p1, p2, p3, p4, p5]).then(values => {  console.log(values); // [ 'one', 'two', 'three', 'four', 'five' ] }, reason => {  console.log(reason) // reject });

5.allSettled

接受一个具有Iterable接口的类型,如数组,Map,Set,传入多个promise,
每个promise状态改变成fulfilled或者rejected之后返回,返回的是一个数组对象,对象中有状态status和每一项的返回结果value

Promise.allSettled([p1, p2, p3, p4, p5]).then(values => {console.log(values); }, reason => {console.log(reason) }); // [ //   { status: 'fulfilled', value: 'one' }, //   { status: 'fulfilled', value: 'two' }, //   { status: 'fulfilled', value: 'three' }, //   { status: 'fulfilled', value: 'four' }, //   { status: 'rejected', reason: 'reject' } // ]

6.race

以快为准,数组中所有的promise对象,有一个先执行了何种状态,该对象就为何种状态,并执行相应函数
接受一个具有Iterable接口的类型,如数组,Map,Set,传入多个promise,
其中有一个promise返回了,不管是fulfilled或者rejected,直接返回这个promise的结果

function p1() {  var promise1 = new Promise(function (resolve, reject) {      console.log("p1的第一条输出语句");      resolve("p1完成");  });  return promise1; } function p2() {  var promise2 = new Promise(function (resolve, reject) {      console.log("p2的第一条输出语句");      setTimeout(() => {        console.log("p2的第二条输出语句");        resolve("p2完成");      }, 2000);  });  return promise2; } function p3() {  var promise3 = new Promise(function (resolve, reject) {    console.log("p3的第一条输出语句");    resolve("p3完成");  });  return promise3; } Promise.race([p1(), p2(), p3()]).then(function (data) {  console.log(data); });// 输出 // p1的第一条输出语句 // p2的第一条输出语句 // p3的第一条输出语句 // p1完成

7.any

接受一个具有Iterable接口的类型,如数组,Map,Set,传入多个promise,
当传入的任何一个promise成功的时候,不管其他是否成功或者失败,会把成功的那个promise返回

如果传入的是一个空的数组(Map,Set),返回一个已失败状态的promise,如下


注意
Promise的以上方法都属于 微任务。当Promise状态变为已解决(resolved)或被拒绝(rejected)时,这些方法会产生微任务。这些微任务会在主线程空闲时按照顺序依次执行。

3. 有什么问题

  • 首先,无法取消 Promise,一旦新建它就会立即执行,无法中途取消。

  • 其次,如果不设置回调函数,Promise 内部抛出的错误,不会反应到外部。

  • 第三,当处于 Pending 状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)。

原文链接:https://www.dianjilingqu.com/746796.html

js基础之Promise详解的评论 (共 条)

分享到微博请遵守国家法律