深入理解JavaScript Promise链式调用与错误处理机制

 更新时间:2024年09月08日 08:59:28   作者:snakeshe1010  
在JavaScript的异步编程中,Promise是一个非常重要的概念,它允许我们以链式的方式处理异步操作,使得代码更加清晰和易于管理,本文将通过一系列代码示例,深入探讨Promise的链式调用和错误处理机制,需要的朋友可以参考下

Promise链式调用基础

Promise的链式调用是通过.then()方法实现的,该方法会返回一个新的Promise对象。这意味着我们可以在一个Promise完成后,继续进行下一个异步操作,形成一条Promise链。

const pro1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve(1);
  }, 1000);
});

const pro2 = pro1.then((data) => {
  console.log(data);
  return data + 1;
});

const pro3 = pro2.then((data) => {
  console.log(data);
});

在上面的例子中,pro1在1秒后解析为1,pro2接着处理pro1的结果,并返回2。pro3则是处理pro2的结果。

错误处理

.catch()方法是Promise链式调用中处理错误的常用方式。它等同于在.then()方法中只传递第二个参数。

new Promise((resolve, reject) => {
  reject(new Error('abc'));
}).catch((err) => {
  console.log('失败了!!', err);
});

链式调用的深入理解

Promise链中的状态传递是异步编程中的一个关键概念。一个Promise的状态(pending、fulfilled、rejected)会影响链中下一个Promise的状态。

const pro1 = new Promise((resolve, reject) => {
  console.log('学习');
  reject(123);
});

const pro2 = pro1.then(() => {
  console.log('考试');
}, (err) => {
  console.log('处理失败', err);
});

console.log(pro2); // Promise {<rejected>: 123}

在这个例子中,pro1被拒绝,因此pro2也会被拒绝,并且会打印出错误信息。

详细规则说明

  • 新任务的状态取决于后续处理:
    • 若没有相关的后续处理,新任务的状态和前任务一致,数据为前任务的数据
const pro1 = new Promise((resolve, reject) => {
  console.log('学习');
  console.log('中了五个亿彩票');
  reject(123)
});

const pro2 = pro1.then(( ) => {
  console.log('考试') 
  // 后续任务只处理了成功,没处理失败,会导致pro2也会失败
  // 此时pro1的状态是reject,原因是123
  // pro2的状态也是rejected,原因是123
});

setTimeout(() => {
  console.log(pro2) // Promise {<rejected>: 123}
},1000)
  • 若有后续处理但还未执行,新任务挂起。
const pro1 = new Promise((resolve, reject) => {
  setTimeout(()=>{
    resolve()
  }, 2000)
});

const pro2 = pro1.then(( ) => {
  console.log('考试') 
});

setTimeout(() => {
  console.log(pro2) // Promise {<pending>},此时任务一学习需要2秒,1秒之后,任务一还没完,那么任务二也是挂起
},1000)
  • 若后续处理执行了,则根据后续处理的情况确定新任务的状态
    • 后续处理执行无错,新任务的状态为完成,数据为后续处理的返回值
const pro1 = new Promise((resolve, reject) => {
  console.log('学习')
  resolve()
});

const pro2 = pro1.then(( ) => {
  console.log('考试' ) 
  return 100
});

setTimeout(() => {
  console.log(pro2) // Promise {<fulfilled>: 100}
},1000)
  • 后续处理执行有错,新任务的状态为失败,数据为异常对象,也就是说看后续任务处理过程中是否报错,前面的任务成功,看后续任务的成功处理是否报错,前面任务失败看后续任务的处理失败过程是否报错
const pro1 = new Promise((resolve, reject) => {
  console.log('学习')
  resolve()  
});

const pro2 = pro1.then(( ) => {
  console.log('考试' ) 
  throw new Error('睡着了!!')
  return 100
});

setTimeout(() => {
  console.log(pro2) // Promise {<rejected>: Error: 睡着了!!at <anonymous>:8:9}
},1000)
  • 后续执行后返回的是一个任务对象,新任务的状态和数据与该任务对象一致
const pro1 = new Promise((resolve, reject) => {
  console.log('学习')
  resolve()
});

const pro2 = pro1.then(( ) => {
  return new Promise((resolve, reject) => {
  })
});

setTimeout(() => {
  console.log(pro2) // Promise {<pending>} pro2的后续处理,返回的是新promise,就要看新的promise状态
},1000)

实战演练

修改上一节课中发送短信的示例,我们可以更好地理解Promise链式调用的实际应用。

function sendMessage(name) {
  return new Promise((resolve, reject) => {
    // 模拟发送表白短信
    setTimeout(() => {
      if (Math.random() <= 0.1) {
        resolve(`${name} -> 帅哥程序员:我是九,你是三,除了你还是你😘`);
      } else {
        reject(`${name} -> 帅哥程序员:你是个好人😜`);
      }
    }, 1000);
  });
}

sendMessage('kitty')
  .catch((reply) => sendMessage('cathy'))
  .catch((reply) => sendMessage('Linda'))
  .then((reply) => {
    console.log(reply);
    console.log('帅哥程序员终于找到了自己的伴侣');
  })
  .catch((reply) => {
    console.log(reply);
    console.log('帅哥程序员命犯天煞孤星,无伴终老,孤独一生');
  });

练习题

  • 下面代码的输出结果是什么
const pro1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve(1);
  }, 1000);
});

const pro2 = pro1.then((data) => {
  console.log(data);
  return data + 1;
});

const pro3 = pro2.then((data) => {
  console.log(data);
});

// console.log(pro1, pro2, pro3);
// promise<pending>, promise<pending>, promise<pending>,前一个任务是pending后续任务肯定也是Pending

setTimeout(() => {
  console.log(pro1, pro2, pro3);
}, 2000);
// 1
// 2
// Promise {<fulfilled>: 1} Promise {<fulfilled>: 2} Promise {<fulfilled>: undefined}
  • 下面代码的输出结果是什么
new Promise((resolve, reject) => {
  resolve(1);
})
  .then((res) => {
    console.log(res);
    return 2;
  })
  .catch((err) => {
    return 3;
  })
  .then((res) => {
    console.log(res);
  });

// 1 2
  • 下面代码的输出结果是什么
new Promise((resolve, reject) => {
  resolve();
})
  .then((res) => {
    console.log(res.toString()); // 报错
    return 2;
  })
  .catch((err) => {
    return 3;
  })
  .then((res) => {
    console.log(res);
  });

// 3
  • 下面代码的输出结果是什么
new Promise((resolve, reject) => {
  throw new Error(1);
})
  .then((res) => {
    console.log(res);
    return new Error('2');
  })
  .catch((err) => {
    throw err;
    return 3;
  })
  .then((res) => {
    console.log(res);
  });

// pro1 reject Error(1)
// pro2 reject Error(1)
// pro3 reject Error(1)
// pro4 reject Error(1)
// 什么都不打印
  • 下面的代码输出什么
const promise1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject();
  }, 1000);
});

const promise2 = promise1.catch(() => {
  return 2;
});

console.log('promise1', promise1);
console.log('promise2', promise2);

// Promise1 {<pending>}
// promise2 Promise {<pending>}

setTimeout(() => {
  console.log('promise1', promise1);
  console.log('promise2', promise2);
}, 2000);
// promise1 Promise {<rejected>: undefined}
// promise2 Promise {<fulfilled>: 2}

以上就是深入理解JavaScript Promise链式调用与错误处理机制的详细内容,更多关于JavaScript Promise链式调用与错误处理的资料请关注脚本之家其它相关文章!

相关文章

  • jQuery实现动态添加、删除按钮及input输入框的方法

    jQuery实现动态添加、删除按钮及input输入框的方法

    这篇文章主要介绍了jQuery实现动态添加、删除按钮及input输入框的方法,涉及jQuery事件响应及页面元素动态操作相关实现技巧,需要的朋友可以参考下
    2017-04-04
  • 微信小程序之裁剪图片成圆形的实现代码

    微信小程序之裁剪图片成圆形的实现代码

    最近在开发小程序,产品经理提了一个需求,要求微信小程序换头像,用户剪裁图片必须是圆形。这篇文章主要介绍了微信小程序之裁剪图片成圆形 ,需要的朋友可以参考下
    2018-10-10
  • 用js将long型数据转换成date型或datetime型的实例

    用js将long型数据转换成date型或datetime型的实例

    下面小编就为大家带来一篇用js将long型数据转换成date型或datetime型的实例。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-07-07
  • 解决微信浏览器Javascript无法使用window.location.reload()刷新页面

    解决微信浏览器Javascript无法使用window.location.reload()刷新页面

    这篇文章主要介绍在微信浏览器Javascript无法使用window.location.reload()刷新页面的解决方法,比较实用,需要的朋友可以参考下。
    2016-06-06
  • javascript ready和load事件的区别示例介绍

    javascript ready和load事件的区别示例介绍

    ready是在DOM加载完成就触发;load是在加载完所有页面内容才会触发,下为大家简要介绍下,不知道的朋友可以参考下
    2013-08-08
  • js实现购物车计算的方法

    js实现购物车计算的方法

    这篇文章主要为大家详细介绍了js实现购物车的计算方法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-08-08
  • TypeScript之调用栈的实现

    TypeScript之调用栈的实现

    这篇文章主要介绍了TypeScript之调用栈的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-12-12
  • js综合应用实例简单的表格统计

    js综合应用实例简单的表格统计

    在做调查问卷的过程中,遇到一个表格的统计问题,一个需要用到js方面的综合知识,感觉还不错所以记录下来与大家分享,感兴趣的朋友可以了解下
    2013-09-09
  • 用JavaScript操作WinRar

    用JavaScript操作WinRar

    Blog的插入HTML功能有誤。 原來在blueidea.com上看到了用ASP執行解壓縮動作的文章,一直沒有去用心看,前日,趁老大不在,爽了一把,把它改成了用JavaScript操作的了。
    2008-04-04
  • js前端实现多图图片上传预览的两个方法(推荐)

    js前端实现多图图片上传预览的两个方法(推荐)

    下面小编就为大家带来一篇js前端实现多图图片上传预览的两个方法(推荐)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-11-11

最新评论