promise的作用
Promise对象可以理解为一次执行的异步操作,解决回调地狱的问题
promise的特点
Promise有三种状态(pending等待、resolve成功、reject失败)
- 对象的状态不受外界影响
- 一旦状态改变,就不会再变,任何时候都可以得到这个结果
基本用法
/*
Promise构造函数接受一个函数作为参数,函数中有两个形参分别是resolve函数和reject函数
reslove函数:将Promise对象的状态从“等待”变为“成功”(从 pending 变为 resolved)。异步操作成功时调用,并将异步操作的结果作为参数传递出去
reject函数:将Promise对象的状态从“等待”变为“失败”(从 pending 变为 rejected),在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去
*/
const promise = new Promise((resolve, reject) => {
if (true) {
// 接口请求成功时调用
resolve('成功');
} else {
// 接口请求失败时调用
reject('失败');
}
});
/* Promise实例生成以后,可以用 .then 方法指定resolved状态.用 .catch 方法 rejected状态的回调函 */
// data 就是 从 resolve 和 reject 返回的结果
promise.then(data => {
console.log(data);
}).catch(err => {
console.log(err);
});
.then()方法
用于预先指定成功和失败的回调函数
/* p.then(成功的回调函数,[失败的回调函数]) 成功的回调函数是必选的*/
p.then(res=>{}[,err=>{}])
.then的链式调用
.then() 方法有一个特性。如果上一个 .then 方法中返回一个新的 Promise实例对象,则可以通过下一个 .then 方法继续处理
/* 需求:
按顺序读取文件内容
*/
// 导入第三方包 then-fs----可以异步读取文件的内容,且返回值为 promise实例对象
import thenFs from "then-fs"
// 通过promise的特性-----链式调用(只要上一个 .then 方法中返回一个新的promise实例对象就可以使用链式调用)
thenFs.readFile("./test/1.txt", "utf-8")
.then(result1 => {
console.log(result1);
return thenFs.readFile("./test/2.txt", "utf-8")
})
.then(result2 => {
console.log(result2);
return thenFs.readFile("./test/3.txt", "utf-8")
})
.then(result3 => {
console.log(result3);
})
.ctach()方法
.catch() 方法用于在 Promise 的链式操作中,如果发生了错误,可以使用 promise.prototype.catch() 方法进行捕获错误和处理,只要在操作中发生了错误就会立刻调用 .catch 方法
/ 假设在当前目录下不存在 11111.txt 文件,此时因文件不存在导致读取文件失败,而不会执行当前 .then 里面的代码
thenFs.readFile("./test/11111.txt", "utf-8")
/*如果把catch放在这个位置,因为当前只有第一个.then 发生了错误,此时已经被处理了,后面 .then 能够正常执行
.catch(err=>{
console.log(err.message);
})
*/
.then(result1 => {
console.log(result1);
return thenFs.readFile("./test/2.txt", "utf-8")
})
.then(result2 => {
console.log(result2);
return thenFs.readFile("./test/3.txt", "utf-8")
})
.then(result3 => {
console.log(result3);
})
// 通过 .catch 方法捕获所有的错误,只要在操作中发生了错误就会立刻调用 .catch 方法,并且在发生错误后面的then都不会在执行
.catch(err=>{
console.log(err.message);
})
Promise.finally()
不管promise最后的状态(无论成功还是失败),在执行完then或catch指定的回调函数以后,都会执行finally方法指定的回调函数。
function getList(flag){
return new Promise((resolve,reject)=>{
flag ? resolve('ok') : reject(err)
})
.then(res=>{})
.catch(err=>{})
.finally(()=>{})
}
Promise.all()方法(等待)
Promise.all()方法 会发起并行的 Promise 异步操作,等所有的异步操作全部结束后才会执行下一步的 .then (等待机制)。在 then 中能获取到所有的结果
/ 定义一个数组,存放三个异步读取文件内容的的操作
const promiseArr = [
thenFs.readFile("./test/1.txt", "utf8"),
thenFs.readFile("./test/2.txt", "utf8"),
thenFs.readFile("./test/3.txt", "utf8")
]
// 调用 Promise.all() 方法,将 promiseArr 数组作为参数。此时当全部的异步操作执行结束后再去执行 then 操作
Promise.all(promiseArr)
.then((result) => { // 所有文件 读取成功才会执行 .then 方法,且读取的顺序就是最后结果的是顺序
console.log(result);
})
.catch(err => { // 捕获 promise 中的异步操作的错误
console.log(err.message);
})
Promise.race()方法(赛跑)
Promise.all()方法 会发起并行的 Promise 异步操作,但只要有任何一个异步操作完成就会立即执行下一步的 .then 操作(赛跑机制)
const promiseArr = [
thenFs.readFile("./test/1.txt", "utf8"),
thenFs.readFile("./test/2.txt", "utf8"),
thenFs.readFile("./test/3.txt", "utf8")
]
// Promise.race()方法只要有任意一个异步操作完成就会执行 then 操作(这里就看哪个文件优先读取成功),只会返回读取最快的结果
Promise.race(promiseArr)
.then(result => {
console.log(result);
})
.catch(err => {
console.log(err.message);
})