当前位置:网站首页>Promise学习(二)一篇文章带你快速了解Promise中的常用API
Promise学习(二)一篇文章带你快速了解Promise中的常用API
2022-08-01 10:21:00 【對不起该用户已成仙】
目录
- 前言
- Promise 常用的API方法
- 1. Promise 构造函数: Promise (excutor) {}
- 2. Promise.prototype.then 方法: (onResolved, onRejected) => {}
- 3. Promise.prototype.catch 方法: (onRejected) => {}
- 4. Promise.resolve 方法: (value) => {}
- 5. Promise.reject 方法: (reason) => {}
- 6. Promise.all 方法: (promises) => {}
- 7. Promise.race 方法: (promises) => {}
- 8. Promise.prototype.finally 方法
- 9. Promise.any 方法
- 10. Promise.allSettled 方法
前言
Promise 常用的API方法
1. Promise 构造函数: Promise (excutor) {}
(1) executor 函数: 执行器(resolve, reject) => {}
(2) resolve 函数: 内部定义成功时我们调用的函数 value => {}
(3) reject 函数: 内部定义失败时我们调用的函数 reason => {}
说明: executor 会在 Promise 内部立即
同步调用
,异步操作在执行器中执行,换话说Promise支持同步也支持异步操作
2. Promise.prototype.then 方法: (onResolved, onRejected) => {}
Promise 实例具有then
方法,也就是说,then
方法是定义在原型对象Promise.prototype
上的。它的作用是为 Promise 实例添加状态改变时的回调函数。前面说过,then方法的第一个参数是resolved
状态的回调函数,第二个参数(可选)是rejected
状态的回调函数。
- onResolved 函数: 成功的回调函数
(value) => {}
- onRejected 函数: 失败的回调函数
(reason) => {}
then
方法返回的是一个新的Promise实例- 注意,不是原来那个Promise实例,因此可以采用链式写法,即
then
方法后面再调用另一个then
方法。
const test = n => {
return new Promise((resolve, reject) => {
// 异步任务
setTimeout(() => {
resolve(n);
}, 1000);
});
}
test(1).then(value => {
console.log(value);
return test(2);
}).then(value => {
console.log(value);
return test(3);
}).then(value => {
console.log(value);
});
上面的代码使用
then
方法,依次指定了多个个回调函数。第一个回调函数完成以后,会将返回结果作为参数,传入第二个回调函数,依次输出结果。
采用链式的then
,可以指定一组按照次序调用的回调函数。这时,前一个回调函数,有可能返回的还是一个Promise
对象(即有异步操作),这时后一个回调函数,就会等待该Promise
对象的状态发生变化,才会被调用。
3. Promise.prototype.catch 方法: (onRejected) => {}
Promise.prototype.catch()
方法是.then(null, rejection)
或.then(undefined, rejection)
的别名,用于 指定发生错误时的回调函数。
- onRejected 函数: 失败的回调函数
(reason) => {}
- 异常穿透使用:运行到最后,没被处理的所有异常错误都会进入这个方法的回调函数中
基本使用:
let p = new Promise((resolve, reject) => {
// 同步调用
// 改变promise对象的状态 失败时
reject('err');
});
// 执行 catch 方法
p.then(reason =>{
console.log(reason);
}).catch(reason => {
console.log(reason);
});
- 如果该对象状态变为
resolved
,则会调用then()
方法指定的回调函数;- 如果异步操作抛出错误,状态就会变为
rejected
,就会调用catch()
方法指定的回调函数,处理这个错误then()
方法指定的回调函数,如果运行中抛出错误,也会被catch()
方法捕获。
4. Promise.resolve 方法: (value) => {}
有时需要将现有对象转为 Promise 对象,Promise.resolve()
方法就起到这个作用。返回一个成功/失败的 promise 对象,直接改变promise状态
- 如果传入的参数为 非Promise类型的对象, 则返回的结果为成功promise对象
- 如果传入的参数为 Promise 对象, 则参数的结果决定了 resolve 的结果
// 非Promise类型
let p1 = Promise.resolve(123);
console.log(p1);
// Promise 对象
let p2 = Promise.resolve(new Promise((resolve, reject) => {
// resolve('ok');
reject('err');
}));
console.log(p2);
// 用catch传入失败的回调,对失败的结果做处理,可解决报错
p2.catch(reason => {
console.log(reason);
});
5. Promise.reject 方法: (reason) => {}
Promise.reject(reason)
方法也会返回一个新的 Promise 实例,该实例的状态为rejected
。返回一个失败的 promise 对象,直接改变promise状态
let p1 = Promise.reject(123);
let p2 = Promise.reject('hahaha');
let p3 = Promise.reject(new Promise((resolve, reject) => {
resolve('ok')
}))
console.log(p1);
console.log(p2);
console.log(p3);
根据代码和结果可以看出,传入
数字
,字符串
,resolved(成功)状态的 Promise 对象
的参数,最后都会返回得到一个rejected(失败)状态的Promise对象
。
6. Promise.all 方法: (promises) => {}
Promise.all()
方法用于将多个 Promise 实例,包装成一个新的 Promise 实例。返回一个新的 promise, 只有所有的 promise 都成功才成功, 只要有一 个失败了就直接失败。
Promise.all()
方法接受一个数组作为参数- 如果不是 Promise 实例,就先调用
Promise.resolve
方法,将参数转为 Promise 实例,再进一步处理。
有一 个失败了就直接失败,代码如下:
// 有一个失败
let p1 = new Promise((resolve, reject) => {
resolve('ok1');
})
let p2 = Promise.resolve('ok2');
let p3 = Promise.resolve('ok3');
// 唯一一个失败
let p4 = Promise.reject('err');
let result = Promise.all([p1, p2, p3, p4]);
console.log(result);
全部成功才成功,代码如下:
// 全部成功
let p1 = new Promise((resolve, reject) => {
resolve('ok1');
})
let p2 = Promise.resolve('ok2');
let p3 = Promise.resolve('ok3');
let result = Promise.all([p1, p2, p3]);
console.log(result);
7. Promise.race 方法: (promises) => {}
Promise.race()
方法同样是将多个 Promise 实例,包装成一个新的 Promise 实例。返回一个新的 promise, 第一个完成
的 promise 的结果状态就是最终的结果状态。
let p1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('ok1');
}, 1000);
})
let p2 = Promise.reject('err');
let p3 = Promise.resolve('ok2');
// 结果由第一个的状态来决定
// 最后为rejected,err
const result = Promise.race([p1, p2, p3]);
console.log(result);
p1延时,开启了异步,其他正常是同步进行,所以
p2>p3>p1
,结果是P2
8. Promise.prototype.finally 方法
finally()
方法用于指定不管 Promise 对象最后状态如何,都会执行的操作。该方法是 ES2018 引入标准的。
finally
方法的回调函数不接受任何参数- 意味着没有办法知道,前面的 Promise 状态到底是
fulfilled
还是rejected
。 - 所以,
finally
方法里面的操作,应该是与状态无关的,不依赖于 Promise 的执行结果。
promise
.then(result => {
}).catch(error => {
}).finally(() => {
});
9. Promise.any 方法
ES2021 新增了Promise.any()方法。该方法接受一组 Promise 实例作为参数,包装成一个新的 Promise 实例返回。只要参数实例有一个变成成功(fulfilled)
状态,包装实例就会变成成功(fulfilled)
状态;如果所有参数实例都变成失败(rejected)
状态,包装实例就会变成失败(rejected)
状态。
- 只要其中的一个 promise 成功,就返回那个已经成功的 promise
Promise.any()
跟Promise.race()
方法很像,只有一点不同,就是不会因为某个 Promise 变成失败(rejected)
状态而结束。
一个 Promise 成功时:
var p1 = Promise.reject('err1');
var p2 = Promise.reject('err2');
var p3 = Promise.resolve('ok1');
var result = [p1, p2, p3];
Promise.any(result).then(value => {
console.log('value: ', value)
}).catch(err => {
console.log('err: ', err)
});
最后结果只得到第一个成功的回调
如果所有传入的 promises 都失败:
var p1 = Promise.reject('err1');
var p2 = Promise.reject('err2');
var p3 = Promise.reject('err3');
var result = [p1, p2, p3];
Promise.any(result).then(value => {
console.log('value: ', value);
}).catch(err => {
console.log('err: ', err);
console.log(err.message);
console.log(err.name);
console.log(err.errors);
});
10. Promise.allSettled 方法
ES2020 引入了Promise.allSettled()
方法,接受一组 Promise 实例作为参数,包装成一个新的 Promise 实例。只有等到所有这些参数实例都返回结果(不管是fulfilled
还是rejected
),包装实例才会结束。
- 可以获取成功或失败的所有状态
- 每个对象都有
status
属性,该属性的值只可能是字符串fulfilled
或字符串rejected
。 fulfilled
时,对象有value
属性,rejected
时有reason
属性,对应两种状态的返回值。
const p1 = Promise.resolve('ok1');
const p2 = Promise.reject('err1');
// 这里的Promise.allSettled 只能得到成功的回调 `fulfilled`
Promise.allSettled([p1, p2]).then(value=> {
console.log(value); //注意,这是 `fulfilled` 的回调函数,只有其状态为成功才能进到这里
});
通过上述代码可知,我们只调取了成功的回调,没有调取失败的回调,但是最后结果列出了所有的回调状态
如果觉得有帮助的话可以继续看下一篇哦!
Promise学习(三)Promise的几个关键性问题 – 状态改变、执行顺序与机制、多任务串联、异常穿透、中断promise链
Authors: min
时间: 2022年7月25日
边栏推荐
- .NET性能优化-使用SourceGenerator-Logger记录日志
- STM32入门开发 介绍IIC总线、读写AT24C02(EEPROM)(采用模拟时序)
- 50.【动态二维数组的运用】
- redis
- C#/VB.NET convert PPT or PPTX to image
- notes....
- July 31, 2022 -- Take your first steps with C# -- Use arrays and foreach statements in C# to store and iterate through sequences of data
- 跨域网络资源文件下载
- Mini Program Graduation Works WeChat Food Recipes Mini Program Graduation Design Finished Products (3) Background Functions
- URL.createObjectURL、URL.revokeObjectURL、Uint8Array、Blob使用详解
猜你喜欢
随机推荐
如何在IntellJ IDEA中批量修改文件换行符
报告:想学AI的学生数量已涨200%,老师都不够用了
xss漏洞学习
我是如何保护 70000 ETH 并赢得 600 万漏洞赏金的
RK3399平台开发系列讲解(内核入门篇)1.52、printk函数分析 - 其函数调用时候会关闭中断
进制与转换、关键字
Drawing arrows of WPF screenshot control (5) "Imitation WeChat"
分类预测 | MATLAB实现1-DCNN一维卷积神经网络分类预测
Batch大小不一定是2的n次幂!ML资深学者最新结论
Visualization - Superset installation and deployment
MySQL 必现之死锁
notes....
EasyRecovery热门免费数据检测修复软件
STM32 Personal Notes - Embedded C Language Optimization
gc的意义和触发条件
The use of scrapy crawler framework
retired paddling
What are the common API security flaws?
深度学习 | MATLAB实现一维卷积神经网络convolution1dLayer参数设定
DBPack SQL Tracing 功能及数据加密功能详解