当前位置:网站首页>Promise 一: 基本问题
Promise 一: 基本问题
2022-08-03 09:29:00 【要不要买菜啊】
目录
1. Promise 是什么
理解
1. 抽象表达:
1) Promise 是一门新的技术(ES6 规范)
2) Promise 是 JS 中进行异步编程的新解决方案
备注:旧方案是单纯使用回调函数
2. 具体表达:
1) 从语法上来说: Promise 是一个构造函数
2) 从功能上来说: promise 对象用来封装一个异步操作并可以获取其成功/ 失败的结果值
2. promise 的状态改变
1. pending 变为 resolved
2. pending 变为 rejected
说明: 只有这 2 种, 且一个 promise 对象只能改变一次
无论变为成功还是失败, 都会有一个结果数据
成功的结果数据一般称为 value, 失败的结果数据一般称为 reason
3.promise 的基本流程

4. promise 的基本使用
使用 1: 基本编码流程

使用 2: 使用 promise 封装基于定时器的异步
使用 3: 使用 promise 封装 ajax 异步请求
2. 为什么要用 Promise?
2.1. 指定回调函数的方式更加灵活
1. 旧的: 必须在启动异步任务前通过回调函数指定
Promise之前的旧方案都是使用回调函数完成异步编程的操作
1、fs 文件操作 如 NodeJS
require('fs').requireFile('./index.html',(error,data)=>{})
2、数据库操作 如 MongoDB MySQL
3、 AJAX 网络请求
$.get('/server',(data)=>{})
4、定时器 setTimeout(()=>{},2000)
2. promise: 启动异步任务 => 返回promie对象 => 给promise对象绑定回调函
数(甚至可以在异步任务结束后指定/多个)
2.2. 支持链式调用, 可以解决回调地狱问题
1. 什么是回调地狱?
回调函数嵌套调用, 外部回调函数异步执行的结果是嵌套的回调执行的条件
比如我要说一句话,语序必须是下面这样的:武林要以和为贵,要讲武德,不要搞窝里斗。如果他们都是异步任务的话,必须进行以下操作,才能保证顺序正确:
setTimeout(function () { //第一层
console.log('武林要以和为贵');
setTimeout(function () { //第二程
console.log('要讲武德');
setTimeout(function () { //第三层
console.log('不要搞窝里斗');
}, 1000)
}, 2000)
}, 3000)
使用promise就可以解决这个问题
function fn(str){
var p=new Promise(function(resolve,reject){
//处理异步任务
var flag=true;
setTimeout(function(){
if(flag){
resolve(str)
}
else{
reject('操作失败')
}
})
})
return p;
}
fn('武林要以和为贵')
.then((data)=>{
console.log(data);
return fn('要讲武德');
})
.then((data)=>{
console.log(data);
return fn('不要搞窝里斗')
})
.then((data)=>{
console.log(data);
})
.catch((data)=>{
console.log(data);
})
2. 回调地狱的缺点?
不便于阅读
不便于异常处理
3. 解决方案?
promise 链式调用
4. 终极解决方案?
async/await
3. 如何使用 Promise?
3.1. API
Promise 构造函数: Promise (excutor) {}
(1) executor 函数: 执行器 (resolve, reject) => {}
(2) resolve 函数: 内部定义成功时我们调用的函数 value => {}
(3) reject 函数: 内部定义失败时我们调用的函数 reason => {}
说明: executor 会在 Promise 内部立即同步调用,异步操作在执行器中执行
Promise.prototype.then 方法: (onResolved, onRejected) => {}
(1) onResolved 函数: 成功的回调函数 (value) => {}
(2) onRejected 函数: 失败的回调函数 (reason) => {}
说明: 指定用于得到成功 value 的成功回调和用于得到失败 reason 的失败回调
返回一个新的 promise 对象
Promise.prototype.catch 方法: (onRejected) => {}
(1) onRejected 函数: 失败的回调函数 (reason) => {}
说明: then()的语法糖, 相当于: then(undefined, onRejected)
Promise.resolve 方法: (value) => {}
(1) value: 成功的数据或 promise 对象
说明: 返回一个成功/失败的 promise 对象
Promise.reject 方法: (reason) => {}
(1) reason: 失败的原因
说明: 返回一个失败的 promise 对象
// 1.创建一个新的promise对象
const p = new Promise((resolve, reject) => {
// 执行器函数 同步回调
// 2.执行异步操作任务
setTimeout(() => {
const time = Date.now();
// 如果当前时间是偶数代表成功,否则代表失败
// 3.1 如果成功了,调用resolve(value)
if (time % 2 == 0) {
resolve("成功的数据, time=" + time);
} else {
// 3.2 如果失败了,调用reject(reason)
reject("失败的数据, time=" + time);
}
});
}, 1000);
//如果传入的参数为 非Promise类型的对象, 则返回的结果为成功promise对象
//如果传入的参数为 Promise 对象, 则参数的结果决定了 resolve 的结果
p.then(
(value) => {
// 接收得到成功的value数据
console.log("onResolved", value);
},
(reason) => {
// 接收得到失败的reason数据
console.log("onRejected", reason);
}
);
Promise.all 方法: (promises) => {}
(1) promises: 包含 n 个 promise 的数组
说明: 返回一个新的 promise, 只有所有的 promise 都成功才成功, 只要有一个失败了就
直接失败
let p1 = new Promise((resolve, reject) => {
resolve('OK');
})
// let p2 = Promise.resolve('Success');
let p2 = Promise.reject('Error');
let p3 = Promise.resolve('Oh Yeah');
//
const result = Promise.all([p1, p2, p3]);
console.log(result); // Uncaught (in promise) Error
Promise.race 方法: (promises) => {}
(1) promises: 包含 n 个 promise 的数组
race就是赛跑的意思,意思就是说, Promise.race([p1, p2, p3])里面哪个结果获得的快,就返回那个结果(只有一个), 不管结果本身是成功状态还是失败状态。
说明: 返回一个新的 promise, 第一个完成的 promise 的结果状态就是最终的结果状态
let p1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('success')
},1000)
})
let p2 = new Promise((resolve, reject) => {
setTimeout(() => {
reject('failed')
}, 500)
})
Promise.race([p1, p2]).then((result) => {
console.log(result)
}).catch((error) => {
console.log(error) // 打开的是 'failed'
})
边栏推荐
- AD环境搭建
- For heavy two-dimensional arrays in PHP
- 110道 MySQL面试题及答案 (持续更新)
- STP生成树(端口状态+端口角色+收敛机制 )|||| STP优化技术( uplinkfast技术+Portfast技术+backbonefast技术 )详解
- Let‘s Encrypt 使用
- go版本升级
- SQL Daily Practice (Nioke New Question Bank) - Day 5: Advanced Query
- 10 Convolutional Neural Networks for Deep Learning 2
- 浅析什么是伪类和伪元素?伪类和伪元素的区别解析
- Add Modulo 10 (规律循环节,代码实现细节)
猜你喜欢
随机推荐
10分钟带你入门chrome(谷歌)浏览器插件开发
线程介绍与使用
scala 并行集合、并行并发、线程安全问题、ThreadLocal
dflow入门2——Slices
行业 SaaS 微服务稳定性保障实战
【LeetCode】112. Path sum
Cartesi 2022 年 7 月回顾
mysql8安装步骤教程
flutter 应用 抓包
dflow入门3——dpdispatcher插件
Add Modulo 10 (规律循环节,代码实现细节)
Network LSTM both short-term and long-term memory
删除文件夹时,报错“错误ox80070091:目录不是空的”,该如何解决?
Let‘s Encrypt 使用
PostgreSQL的架构
MySQL——几种常见的嵌套查询
MySQL的分页你还在使劲的limit?
播放量暴涨2000w+,单日狂揽24w粉,内卷的搞笑赛道还有机会
二叉查找树的综合应用
2022最新整理软件测试常见面试题附答案