当前位置: 首页 > news >正文

ES6的promise

Promise是什么

1、Promise是js中的一个原生对象,是一种异步编程的解决方案。可以替换掉传统的回调函数解决方案,将异步操作以同步的流程表达出来。

2、Promise有三种状态:pending(初始化)、fulfilled(成功)、rejected(失败)

可以通过resolve()与reject()改变当前的promise对象的状态

● resolve()使当前promise对象状态改为fulfilled

● reject()使当前promise对象状态改为rejected

● 一般抛出异常也会导致promise对象状态改为rejected

3、相关概念

回调函数:当一个函数作为参数传入另一个函数中,当满足一定条件后该函数才执行,这种函数就称为回调函数。例如我们熟悉的定时器就存在回调函数。

同步任务:同步任务在主线程上排队执行,只有前一个任务执行完毕,才能执行下一个任务。

异步任务:异步任务不进入主线程,而是进入异步队列,前一个任务是否执行完毕不影响下一个任务的执行。

为什么使用Promise

Promise对象提供了简洁的API,使得控制异步操作更加容易。可以很好地解决回调地狱问题

1、回调地狱

为了在异步函数当中顺序执行代码而而不断嵌套调用回调函数,例如以下代码:

setTimeout(() => {console.log('setTimeout1');setTimeout(() => {console.log('setTimeout2');setTimeout(() => {console.log('setTimeout3');}, 1000);}, 2000);
}, 3000);// 分别输出setTimeout1、setTimeout2、setTimeout3

2、Promise链式编程解决回调地狱

getPromise(str, time) {return new Promise((resolve, reject) => {setTimeout(() => {resolve(str)}, time);});
}
const p1 = this.getPromise('setTimeout1', 3000);
const p2 = this.getPromise('setTimeout2', 2000);
const p3 = this.getPromise('setTimeout3', 1000);
p1.then((data1) => {console.log(data1);return p2;
})
.then((data2) => {console.log(data2);return p3;
})
.then((data3) => {console.log(data3);
})// 依次输出setTimeout1、setTimeout2、setTimeout3

基本用法

1、 new实例化一个promise对象,构造函数中接收一个函数作为参数,该函数支持传入2个参数resolve和reject。

2、将需要处理的异步任务写在该函数内,异步任务执行成功时调用resolve返回结果,执行失败时调用reject回调函数。

3、通过promise.then接收处理成功时响应的数据,catch接收处理失败时响应的数据。

const promise1 = new Promise((resolve, reject) => {axios.get("/api/mock-data/list/v1").then((e) => {if (e.data.status == 200) {resolve(e.data);} else {reject({errCode: -1});}});
});
promise1.then((data) => {console.log('接口返回数据===',data);
})
.catch((err) => {console.log('接口响应错误===',err);
});
// 模拟接口数据1:通过then()获取
{status: 200,message: 'success',data: [{id: 1,name: 'xiaoming',age: '21',job: '前端工程师'}, {id: 2,name: 'xiaozhang',age: '28',job: '后端工程师'}]
}
// 模拟接口数据2:通过catch()捕获
{status: 404,message: 'Not Found',data: null
}

常用API

promise.then():获取异步任务的成功结果,支持2个函数参数(成功和失败回调),一般来说then中只处理成功的

promise.catch():获取异步任务的失败结果,和then函数参数中失败回调作用一样,处理错误,由于Promise抛出错误具有冒泡性质,能够不断传递,会传到catch中,所以一般来说所有错误处理放在catch中,then中只处理成功的,同时catch还会捕捉resolved中抛出的异常(代码报错)

promise.finally():异步任务成功与否,都会执行

Promise.all():Promise.all([promise1,promise2])——参数是对象数组。以慢为准,等数组中所有的promise对象状态为resolved时,该对象就为resolved;只要数组中有任意一个promise对象状态为rejected,该对象就为rejected

const p1 = new Promise((resolve, reject) => {resolve({ errCode: 0 });
});
const p2 = new Promise((resolve, reject) => {resolve({ errCode: -1 });
});
const p3 = new Promise((resolve, reject) => {resolve({ errCode: -2 });
});
const promises = Promise.all([p1, p2, p3]);
promises
.then((data) => {console.log("Promise.all.then===", data);
})
.catch((err) => {console.log("Promise.all.catch===", err);
});
// 运行结果为:Promise.all.then===
//[
//    {
//        "errCode": 0
//    },
//    {
//        "errCode": -1
//    },
//    {
//        "errCode": -2
//    }
//]
const p1 = new Promise((resolve, reject) => {resolve({ errCode: 0 });
});
const p2 = new Promise((resolve, reject) => {reject({ errCode: -1 });
});
const p3 = new Promise((resolve, reject) => {reject({ errCode: -2 });
});
const promises = Promise.all([p1, p2, p3]);
// const promises = Promise.race([p2, p1, p3]);
promises
.then((data) => {console.log("Promise.all.then===", data);
})
.catch((err) => {console.log("Promise.all.catch===", err);
});
// 运行结果为:Promise.all.catch===
//{
//   "errCode": -1
//}

Promise.race():Promise.race([promise1,promise2])——参数是对象数组。以快为准,数组中所有的promise对象,有一个先执行了何种状态,该对象就为何种状态,并执行相应函数

const p1 = new Promise((resolve, reject) => {reject({ errCode: 0 });
});
const p2 = new Promise((resolve, reject) => {resolve({ errCode: -1 });
});
const p3 = new Promise((resolve, reject) => {resolve({ errCode: -2 });
});
const promises = Promise.race([p2, p1, p3]);
promises
.then((data) => {console.log("Promise.all.then===", data);
})
.catch((err) => {console.log("Promise.all.catch===", err);
});
// 运行结果为:Promise.all.then===
//{
//    "errCode": -1
//}

Promise缺点

代码冗余,异步任务通过new Promise包装后,都需要使用then调用,导致一眼看出都是then..then..then,不利于代码维护。

async/await

async/await 是ES7提出的基于Promise的解决异步的最终方案。

async:是一个加在函数前的修饰符,被async定义的函数会默认返回一个Promise对象resolve的值。因此对async函数可以直接then,返回值就是then方法传入的函数。

async fn() {return 123456;
},
this.fn().then((data) => {console.log('async===',data);
})
// 输出为:async=== 123456
// 注意:未加async修饰的函数,是不能直接.then的

await: 也是一个修饰符,只能放在async定义的函数内。可以理解为等待

await 修饰Promise对象:可以获取Promise中返回的内容(resolve或reject的参数),且取到值后语句才会往下执行;

示例:

async fn() {let data = '';axios.get("/api/mock-data/list/v1").then((e) => {data = e.data;});console.log('data===',data);// 输出data值为''
}

await修饰后:new Promise可以省略

async fn() {let data = '';data = await new Promise((resolve, reject) => {axios.get("/api/mock-data/list/v1").then((e) => {resolve(e.data);});});console.log('data===',data);// 输出data为接口返回值
}

总结:await实际会暂停函数的执行,直到promise状态变为完成,然后继续执行。

async fn() {console.log('123');let data1 = await new Promise((resolve, reject) => {axios.get("/api/mock-data/list/v1").then((e) => {resolve(e.data);});});let data2 = await new Promise((resolve, reject) => {setTimeout(() => {resolve('success');}, 3000);});console.log('456');console.log('data1===',data1);console.log('data2===',data2);
},
this.fn();//立即输出123,3秒后分别输出456、data1、data2

tips

当浏览器出现报错Uncaught (in promise) err时,检查是否有reject错误未捕获,增加catch分支即可。

http://www.lryc.cn/news/423950.html

相关文章:

  • 轻松找回:如何在PostgreSQL 16中重置忘记的数据库密码
  • EVAL长度突破限制
  • 如何判断树上一个点是否在直径上
  • docker 部署 RabbitMQ
  • 设计模式 - 过滤器模式
  • 使用 Locust 进行本地压力测试
  • 【图形学】TA之路-矩阵应用平移-旋转-大小
  • Spring 循环依赖解决方案
  • 可视化大屏:如何get到领导心目中的“科技感”?
  • 基于Python的金融数据采集与分析的设计与实现
  • 使用Sanic和SSE实现实时股票行情推送
  • redis散列若干记录
  • Java面试八股之什么是STOMP协议
  • 【自用】Python爬虫学习(一):爬虫基础与四个简单案例
  • [python]uiautomation.WindowControl函数用法
  • 学习记录第二十七天
  • servlet的执行顺序
  • Go语言 类封装和绑定方法
  • DirectShow过滤器开发-写WAV音频文件过滤器
  • php根据截止时间计算剩余的时间,并且在剩余时间不足1天时仅显示小时数
  • Docker最佳实践进阶(一):Dockerfile介绍使用
  • Anything in Any Scene:无缝融入任何场景,实现逼真视频对象插入技术
  • 安卓开发中的AppCompat框架|安卓系统|安卓应用|兼容性|UI组件|核心组件|ActionBar|Fragment|最佳实践|框架|移动开发|移动应用
  • React使用useRef ts 报错
  • python-信息交互-pyautogui
  • flink1.18 编译遇到的问题
  • 2024年8月份编译Openwrt系统基础
  • Vue3+vite+ts 项目使用mockjs
  • 动态规划(二)——例题
  • Node.js中判断是文件还是文件夹的多种方法