再次梳理一下同步和异步的区别:
同步:在执行一段代码,没有返回结果之前,则不执行后面的代码。会阻塞后面代码的执行。
异步:与同步执行相反,在执行执行一段代码没有返回结果时,通过一个回调函数来处理这个结果,继续执行后面的代码。
在ES6中,用Promise对象来表示异步的最终完成和结果。
Promise以下三个状态:
待定(pending): 初始状态。
已兑现(fulfilled): 意味着操作成功完成。
已拒绝(rejected): 意味着操作失败。
pending状态要么转化为fulfilled,要么转化为rejected状态,通过promise的then方法和catch方法来返回对应的promise对象。
const fs = require("fs")
let readFilePromise = (filename) => {
return new Promise((resolve,) => {
fs.readFile(filename, (err,) => {
if (err) {
reject(err)
} else {
resolve(data)
}
})
})
}
readFilePromise('./fs.json').then(res => {
console.log("res", res)
})
每次任务执行结束后产生的失败是直接被catch捕捉到的,因为Promise采用的是错误冒泡的方式,产生的错误会一直往后传递,直到被catch捕获。这样我们就不用频繁的检查错误了。
这就是Promise的好处:通过链式调用的方式来解决了多层嵌套的问题;Promise通过错误冒泡来统一做错误处理,这样避免每个任务都要错误检查导致代码混乱的问题。
Promise静态方法
Promise.all
参数是可迭代的对象,比如数组,Promise.all是把多个异步操作并行执行,所有的异步都成功后才返回成功,返回的值也是按照入参的顺序来返回。如果有一个异步失败,就返回失败,会把第一个异步失败当成Promise.all的失败结果返回。
//1.获取轮播数据列表
function getBannerList() {
return new Promise((resolve,) => {
setTimeout(function () {
resolve('banner')
}, 300)
})
}
//2.获取店铺列表
function getStoreList() {
return new Promise((resolve,) => {
setTimeout(function () {
resolve('store')
}, 500)
})
}
//3.获取分类列表
function getCategoryList() {
return new Promise((resolve,) => {
setTimeout(function () {
reject("失败了")
// resolve('category')
}, 700)
})
}
function initLoad() {
Promise.all([getBannerList(), getStoreList(), getCategoryList()])
.then(res => {
console.log(res)
}).catch(err => {
console.log(err)
})
}
initLoad()
Promise.allSettled
和Promise.all相似,返回一个对象数组,每个对象表示对应的异步任务的结果,不管异步任务的结果fulfilled还是reject。
Promise.allSettled适合多个彼此不依赖的异步任务,Promise.all更合适多个相互依赖的异步任务。
对之前的案例代码稍微改造一下:
function initLoad() {
Promise.allSettled([getBannerList(), getStoreList(), getCategoryList()])
.then(res => {
console.log(res)
}).catch(err => {
console.log(err)
})
}
initLoad(); // [{ status: 'fulfilled', value: 'banner' },{ status: 'fulfilled', value: 'store' },{ status: 'rejected', reason: '失败了' }]
Promise.any
传入一个可迭代的参数,如数组。
返回已经成功的异步任务,如果有多个异步都fulfilled了的,那就返回第一个。如果所有的参数都变成rejected的话,那么就返回一个rejected。
//1.获取轮播数据列表
function getBannerList() {
return new Promise((resolve,) => {
setTimeout(function () {
reject('banner')
}, 300)
})
}
//2.获取店铺列表
function getStoreList() {
return new Promise((resolve,) => {
setTimeout(function () {
reject('store')
}, 500)
})
}
//3.获取分类列表
function getCategoryList() {
return new Promise((resolve,) => {
setTimeout(function () {
reject("失败了")
// resolve('category')
}, 700)
})
}
function initLoad() {
Promise.any([getBannerList(), getStoreList(), getCategoryList()])
.then(res => {
console.log(res)
}).catch(err => {
console.log(err)
})
}
initLoad(); // [AggregateError: All promises were rejected]
Promise.race
返回一个Promise对象,只要所有参数中有一个异步任务变成fulfilled或者rejected,那么就返回结果【fulfilled或者是rejected】
这就是Promise常见的几个静态方法。