Promise讲解,async和await修饰符
Promise的作用
Promise是Es6中的语法,用于解决异步回调的问题(回调地狱)。
回调地狱:回调函数中嵌套回调
Promise解决了回调地狱
new Promise(( resolve, reject ) =>{})
//Promise接受一个函数作为参数
//在参数函数中有两个参数// resolve: 成功函数// reject: 失败函数
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);
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);});
解决回调地狱
需求:通过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);});
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修饰符相关推荐
- ES6中的promise、async、await用法详解
<!DOCTYPE html> <html> <head><title>Promise.async.await</title> </h ...
- 详解promise、async和await的执行顺序
说明: 本文摘自 详解 promise.async和await的执行顺序. 1.题目和答案 一道题题目:下面这段promise.async和await代码,请问控制台打印的顺序? async func ...
- promise、async和await
promise JavaScript是单线程 因为js语言的一大特点就是单线程,也就是说,同一个时间只能做一件事. 异步任务 但这样很容易造成阻塞,所以把任务分成了同步任务和异步任务两种,异步模式可以 ...
- ES6常问面试题(Promise,async和await 等)
文章目录 ES6新特征 Promise Promise 构造函数: 箭头函数 set set的方法: set的应用 map Map的属性和方法: 模块化 export的语法 import的语法 迭代器 ...
- JS - 15 - 异步、Promise、async、await
Promise 类似 java 的 Callable then 方法 类似 java 的 Future 下一篇: <JS - 16 - 任务调度.宏任务.微任务.轮询> PromiseA+ ...
- js 异步函数讲解: Promise、async和await示例
ECMAScript 2015,也称为 ES6,引入了 JavaScript Promise 对象,用于异步执行运行时间较长的任务. 有两种方式来实现异步编程: 一是使用Promise对象,二是使用a ...
- 理解promise、async 和await之间的执行关系
先看下面的例子 console.log('script start'); async function async1(){console.log('async1 start');await async ...
- promise与async和await的区别
async await(等待):必须把这件事干完,才能继续走.这个语法比promise更加高级,也更加好用.如果不加await,不让走 什么是async/await? async/await是写异步代 ...
- 异步编程:一次搞懂Promise,async,await
文章目录 前言 一.回调函数 二.Promise 三.错误处理 四.async/await await使用时的陷阱 1 2 3 总结 前言 异步编程允许我们在执行一个长时间任务时,程序不需要进行等待, ...
最新文章
- linux中sort命令
- 从程序员的角度分析微信小程序
- 2017 Vue.js 2快速入门指南
- sqlserver服务启动失败_条码打印软件连接SQL数据库出现TCP连接失败解决办法
- 苏宁推出物联网应用“云居”
- 【2013年04月18号】
- 演示如何利用log4net记录程序日志信息
- HighCharts:PlotLine的label文字不显示
- 和风天气OUC——通过搜索城市快速查询天气
- 从随机森林到极端随机森林,再到深度森林
- 最近选购MP3而有感便携追求音质的一些心得
- UI美化APICLOUD千月影视APP源码
- origin | 绘制倒置柱状图 | y轴向下柱状图 | y轴正负对比柱状图 | 添加图层 | 垂线图
- 计算机分区硬盘有写保护,磁盘被写保护怎么办?总结几种去掉磁盘写保护的方法...
- h5底部输入框被键盘遮挡_搜遍整个谷歌, 只有我是在认真解决安卓端hybrid app键盘遮挡输入框的问题...
- 2022年终总结-知识沉淀、疫情、展望未来
- 报告:加密货币和石油市场暴跌是市场接近“闪电崩盘”的标志
- 制作立体图像(上):红蓝眼镜原理
- javascript中call的用法总结
- 7-18 Decimal Equivalent of a Binary Number (10 分)
热门文章
- java秒嘀短信登录验证实例_java web实现手机短信验证码登录实例
- IDEA从零到精通(24)之lombok插件的安装与使用
- 学习是什么?我们要怎么学习?
- matlab 函数 c++ 复写之randperm
- Visor Finance 攻击分析
- echarts柱状图优化(柱状图渐变色实现的两种方式)
- Struts2项目实战 微云盘(二):项目结构
- 如何使用echart的Graph图实现一个流程控制图
- 【区块链技术】区块链入门详解①
- ‘StringBuilder‘ can be replaced with ‘String‘