1. Promise的作用

Promise是Es6中的语法,用于解决异步回调的问题(回调地狱)。

回调地狱:回调函数中嵌套回调

Promise解决了回调地狱

new Promise(( resolve, reject ) =>{})
//Promise接受一个函数作为参数
//在参数函数中有两个参数// resolve: 成功函数// reject: 失败函数
  1. Promise的状态

总结:

Promise对象中有一个叫promiseState的属性,它表示了Promise对象的状态

pending:表示等待中状态

fulfilled:表示成功状态

rejected:表示失败状态

pending(等待中):

// 实例化Promise对象后就是pending状态let p = new Promise(function (reslove, reject) {});console.log(p);

fulfilled(成功):

 let p = new Promise(function (reslove, reject) {reslove()// 当调用成功函数后,promise的状态就是成功(fulfilled)});console.log(p);

rejected(失败):

let p = new Promise(function (reslove, reject) {reject(); // 当调用失败函数后,promise的状态就是成功(rejected)});console.log(p);
  1. Promise方法

总结:Promise原型上有then和catch方法

.then()方法函数:它可以接收两个参数,两个参数都是函数。返回值是一个Promise对象。

1.当Promise的状态是成功(fulfilled)时执行第一个参数函数,用于成功时调用。

2.当Promise的状态是失败(rejected)时执行第二个参数函数,相当于.catch()方法,用于失败时调用。

.catch()方法:它的参数是一个函数参数

1. 当Promise的状态是失败(rejected)被执行。

2. 当Promise执行过程出现代码错误时,被执行。

注:当promise状态为pending状态时,.then()和.catch()都不会执行。

.then()方法

当promise的状态为fulfilled时

let p = new Promise(function (reslove, reject) {// 通过调用reslove, reject传递参数,改变当前promise的状态let value = "123123";reslove(value); // 成功状态});p.then((val) => {//当promise的状态为fulfilled时调用then方法的第一个参数函数console.log("成功的结果", val);},(err) => {console.log("失败的结果", err);});console.log(p);

当promise的状态为reject时

let p = new Promise(function (reslove, reject) {// 通过调用reslove, reject传递参数,改变当前promise的状态let err = "err";reject(err); // 失败状态});p.then((val) => {//当promise的状态为fulfilled时调用then方法的第一个参数函数console.log("成功的结果", val);},(err) => {//当promise的状态为rejected时调用then方法的第二个参数函数console.log("失败的结果", err);});console.log(p);

.catch()方法

catch中的参数函数在什么时候被执行?

1. 当Promise的状态为rejcted时被执行,注:在链式写法时,当then方法有第二个函数参数时,catch方法不会被调用

  let p = new Promise(function (reslove, reject) {// 通过调用reslove, reject传递参数,改变当前promise的状态let err = "err";reject(err); // 失败状态});p.then((val) => {console.log("成功的结果", val);}).catch((err) => {//当promise的状态为rejected时调用catch方法console.log(err);});console.log(p);

2. 当Promise执行过程出现代码错误时,被执行

 let p = new Promise(function (reslove, reject) {throw new Error("出错了"); // 让promise执行出错});p.then((val) => {console.log("成功的结果", val);}).catch((err) => {//当Promise执行过程出现代码错误时console.log(err);});
  1. 解决回调地狱

需求:通过id请求用户名.再根据用户名获取用户email,通过emai获取消息内容

   //  通过id请求用户名.再根据用户名获取用户email,通过emai获取消息内容let idArr = [{ id: 1, name: "小李" },{ id: 2, name: "小刘" },{ id: 3, name: "小喻" },{ id: 4, name: "小蒋" },];let emailArr = [{ name: "小李", email: "小李QQ" },{ name: "小刘", email: "小刘QQ" },{ name: "小喻", email: "小喻QQ" },{ name: "小蒋", email: "小蒋QQ" },];let msgArr = [{ email: "小李QQ", msg: "小李划水" },{ email: "小刘QQ", msg: "小刘划水" },{ email: "小喻QQ", msg: "小喻划水" },{ email: "小蒋QQ", msg: "小蒋划水" },];// 模仿接口,通过id查询用户名function findName(id) {let userName = "";idArr.forEach((item) => {if (item.id == id) {userName = item.name;}});return userName;}// 模仿接口,通过用户名查询emailfunction findEmail(name) {let userEmail = "";emailArr.forEach((item) => {if (item.name == name) {userEmail = item.email;}});return userEmail;}// 模仿接口,通过email查询消息function findMsg(email) {let userMsg = "";msgArr.forEach((item) => {if (item.email == email) {userMsg = item.msg;}});return userMsg;}

普通写法

new Promise(function (reslove, reject) {// 调用findName接口,通过id查找用户名let userName = findName(1);if (userName != "") {// 查找到用户,改变promise状态为成功,并传值reslove(userName);} else {// 没有查找到用户,改变promise状态为失败reject("没有查找到用户");}}).then((userName) => {// 调用findEmail接口,通过用户名查找emaillet userEmail = findEmail(userName);return new Promise(function (reslove, reject) {if (userEmail != "") {reslove(userEmail);} else {reject("没有查找到邮箱");}});}).then((userEmail) => {// 调用findMsg接口,用过email查找到消息let userMsg = findMsg(userEmail);console.log(userMsg);}).catch((err) => {// catch方法放在最后,用于捕获错误console.log(err);});

优化写法

牢记:promise是为了解决回调地狱问题

1.promise处于成功状态时调用then(),promise处于失败状态时调用catch()。

2.通过调用reslove()改变promise状态为成功,调用reject()改变promise状态为失败。

3.then()方法的返回值是promise对象,且reslove()可以携带参数,所以我们可以采用链式写法。

4.因为then()方法的返回值是promise对象,我们可以在then()方法中直接使用return,把值返回出去,在下一级的then()方法会接收到值。使用return后,当前promise对象的状态为成功。代码出现错误时,当前promise的状态为失败,并且。catch()方法会捕获错误

new Promise(function (reslove, reject) {// 调用findName接口,通过id查找用户名let userName = findName(1);if (userName != "") {reslove(userName);} else {reject("没有查找到用户");}}).then((userName) => {// 调用findEmail接口,通过用户名查找emaillet userEmail = findEmail(userName);return userEmail //then()方法返回值是promise 使用return后,当前promise对象的状态为成功// ...后续链式写法同样可以使用return}).then((userEmail) => {// 调用findMsg接口,用过email查找到消息let userMsg = findMsg(userEmail);console.log(userMsg);}).catch((err) => {// catch方法放在最后,用于捕获错误console.log(err);});
  1. async和await

async

使用async修饰函数,函数的返回值是一个promise对象,这个promise对象的值由async修饰的函数的返回值决定

1.如果被async修饰的函数的返回值是一个非Promise类型的数据

async function main() {//   1.如果被async修饰的函数的返回值是一个非Promise类型的数据return "非Promise类型的数据"; //一个字符串 数字 布尔值等都是成功的Promise对象}let result = main();console.log(result);// main()函数的返回值是promise对象,它的值由mian()函数return的值决定

2.如果被async修饰的函数的返回值是一个promise对象,

async function main() {// 2. 如果返回的时一个Promise对象return new Promise((resolve, reject) => {resolve("OK"); //返回的是成功Promise对象,状态值:[[PromiseState]]:"fulfilled"//    reject("Err") //返回的是失败Promise对象,状态值:[[PromiseState]]:"rejected"});}let result = main();console.log(result);// main()函数的返回值是promise对象,它的值由返回的resolve(),reject()的值决定

3.如果被async修饰的函数抛出异常

  async function main() {return new Promise((resolve, reject) => {// 3. 抛出异常throw "oh No"; // 状态值:[[PromiseState]]:"rejected",结果是抛出的值});}let result = main();console.log(result);// main()函数异常,返回的promise状态为失败

await

注:await 必须写在 async 函数中, 但 async 函数中可以没有 await

await 右侧的表达式一般为 promise 对象, 但也可以是其它的值

1. 如果await 右侧的表达式是 promise 对象, await 返回的是 promise 成功的值也就是resolve()中的值

2. 如果await 右侧的表达式是其它值, 直接将此值作为 await 的返回值

3.注:如果await 右侧的表达式是 promise 对象,且右边的promise状态为失败,就会抛出异常, 需要通过 try...catch 捕获处理

举例:

1.如果await右边是promise对象

 async function main() {let p = new Promise(function (reslove, reject) {reslove("我是成功时候的值");});let res = await p;console.log(res);// 打印:我是成功时候的值}main();// async 修饰的main()函数中,await右边是promise对象,所以await修饰的返回值是reslove()中的值

2.如果右侧为其他类型的数据

async function main() {let val = 20;let res = await val;console.log(res); // 打印:20}main();// async 修饰的main()函数中,await右边是其他类型的数据,await直接将值返回

3.如果右侧的promise的状态是失败

async function main() {let p = new Promise(function (reslove, reject) {reject("错误");});try {let res = await p;} catch (error) {console.log(error); // 捕获错误,值为reject()的值}}main();// async 修饰的main()函数中,await右边是promise对象且promise的状态为失败,那么就要使用try...catch捕获错误

async和await结合

    //  通过id请求用户名.再根据用户名获取用户email,通过emai获取消息内容let idArr = [{ id: 1, name: "小李" },{ id: 2, name: "小刘" },{ id: 3, name: "小喻" },{ id: 4, name: "小蒋" },];let emailArr = [{ name: "小李", email: "小李QQ" },{ name: "小刘", email: "小刘QQ" },{ name: "小喻", email: "小喻QQ" },{ name: "小蒋", email: "小蒋QQ" },];let msgArr = [{ email: "小李QQ", msg: "小李划水" },{ email: "小刘QQ", msg: "小刘划水" },{ email: "小喻QQ", msg: "小喻划水" },{ email: "小蒋QQ", msg: "小蒋划水" },];// 模仿接口,通过id查询用户名function findName(id) {let userName = "";idArr.forEach((item) => {if (item.id == id) {userName = item.name;}});return userName;}// 模仿接口,通过用户名查询emailfunction findEmail(name) {let userEmail = "";emailArr.forEach((item) => {if (item.name == name) {userEmail = item.email;}});return userEmail;}// 模仿接口,通过email查询消息function findMsg(email) {let userMsg = "";msgArr.forEach((item) => {if (item.email == email) {userMsg = item.msg;}});return userMsg;}async function main() {let userName = await findName(1);let userEmail = await findEmail(userName);let userMsg = await findMsg(userEmail);console.log(userMsg);}main();// 使用await将异步代码同步化,await顾名思义,他会等待右边的表达式执行完再往下执行

Promise讲解,async和await修饰符相关推荐

  1. ES6中的promise、async、await用法详解

    <!DOCTYPE html> <html> <head><title>Promise.async.await</title> </h ...

  2. 详解promise、async和await的执行顺序

    说明: 本文摘自 详解 promise.async和await的执行顺序. 1.题目和答案 一道题题目:下面这段promise.async和await代码,请问控制台打印的顺序? async func ...

  3. promise、async和await

    promise JavaScript是单线程 因为js语言的一大特点就是单线程,也就是说,同一个时间只能做一件事. 异步任务 但这样很容易造成阻塞,所以把任务分成了同步任务和异步任务两种,异步模式可以 ...

  4. ES6常问面试题(Promise,async和await 等)

    文章目录 ES6新特征 Promise Promise 构造函数: 箭头函数 set set的方法: set的应用 map Map的属性和方法: 模块化 export的语法 import的语法 迭代器 ...

  5. JS - 15 - 异步、Promise、async、await

    Promise 类似 java 的 Callable then 方法 类似 java 的 Future 下一篇: <JS - 16 - 任务调度.宏任务.微任务.轮询> PromiseA+ ...

  6. js 异步函数讲解: Promise、async和await示例

    ECMAScript 2015,也称为 ES6,引入了 JavaScript Promise 对象,用于异步执行运行时间较长的任务. 有两种方式来实现异步编程: 一是使用Promise对象,二是使用a ...

  7. 理解promise、async 和await之间的执行关系

    先看下面的例子 console.log('script start'); async function async1(){console.log('async1 start');await async ...

  8. promise与async和await的区别

    async await(等待):必须把这件事干完,才能继续走.这个语法比promise更加高级,也更加好用.如果不加await,不让走 什么是async/await? async/await是写异步代 ...

  9. 异步编程:一次搞懂Promise,async,await

    文章目录 前言 一.回调函数 二.Promise 三.错误处理 四.async/await await使用时的陷阱 1 2 3 总结 前言 异步编程允许我们在执行一个长时间任务时,程序不需要进行等待, ...

最新文章

  1. linux中sort命令
  2. 从程序员的角度分析微信小程序
  3. 2017 Vue.js 2快速入门指南
  4. sqlserver服务启动失败_条码打印软件连接SQL数据库出现TCP连接失败解决办法
  5. 苏宁推出物联网应用“云居”
  6. 【2013年04月18号】
  7. 演示如何利用log4net记录程序日志信息
  8. HighCharts:PlotLine的label文字不显示
  9. 和风天气OUC——通过搜索城市快速查询天气
  10. 从随机森林到极端随机森林,再到深度森林
  11. 最近选购MP3而有感便携追求音质的一些心得
  12. UI美化APICLOUD千月影视APP源码
  13. origin | 绘制倒置柱状图 | y轴向下柱状图 | y轴正负对比柱状图 | 添加图层 | 垂线图
  14. 计算机分区硬盘有写保护,磁盘被写保护怎么办?总结几种去掉磁盘写保护的方法...
  15. h5底部输入框被键盘遮挡_搜遍整个谷歌, 只有我是在认真解决安卓端hybrid app键盘遮挡输入框的问题...
  16. 2022年终总结-知识沉淀、疫情、展望未来
  17. 报告:加密货币和石油市场暴跌是市场接近“闪电崩盘”的标志
  18. 制作立体图像(上):红蓝眼镜原理
  19. javascript中call的用法总结
  20. 7-18 Decimal Equivalent of a Binary Number (10 分)

热门文章

  1. java秒嘀短信登录验证实例_java web实现手机短信验证码登录实例
  2. IDEA从零到精通(24)之lombok插件的安装与使用
  3. 学习是什么?我们要怎么学习?
  4. matlab 函数 c++ 复写之randperm
  5. Visor Finance 攻击分析
  6. echarts柱状图优化(柱状图渐变色实现的两种方式)
  7. Struts2项目实战 微云盘(二):项目结构
  8. 如何使用echart的Graph图实现一个流程控制图
  9. 【区块链技术】区块链入门详解①
  10. ‘StringBuilder‘ can be replaced with ‘String‘