前端项目中常用es6知识总结 -- Promise逃脱回调地狱

时间:2021-05-18 09:13:44

项目开发中一些常用的es6知识,主要是为以后分享小程序开发、node+koa项目开发以及vueSSR(vue服务端渲染)做个前置铺垫。

项目开发常用es6介绍

  • 1、块级作用域 let const

  • 2、箭头函数及this指向

  • 3、promise、

  • 4、async await语法
  • 4、模块化 module export和import

  • 5、解构赋值、字符串模板

  • ……

Promise

Promise是什么?不妨直接打印出来看吧! 在浏览器控制台输入console.dir( Promise )回车会有惊喜。

// 大家在浏览器控制台输入console.dir( Promise )看一下哈!!!

可以看到Promise是一个构造函数,它跟JS中的Date、Array等构造函数类似,使用new操作符实例化之后就可以通过传参和调用方法的形式来完成某些特定的功能:

var date = new Date("2018-12-24 15:46:10");
date.getTime() //
date.getFullYear() //
date.getDate() //

同样,我们也需要使用new操作符来实例化Promise构造函数,与其他构造函数不同的是Promise接收一个函数作为参数。该函数又接收两个参数,分别是resolve和reject,resolve和reject也是函数(javascript内置的)且这两个函数都有各自不同的作用。 resolve函数的作用是:将Promise对象的状态从未完成变为成功(即从 pending 变为 resolved) reject函数的作用是:将Promise对象的状态从未完成变为失败(即从 pending 变为 rejected) 无论结果是成功还是失败,都可以将需要传递的参数通过该函数传递出去,以下是代码示例:

var promise = new Promise(function(resolve, reject) {
setTimeout(function() {
resolve("我是数据")
}, 1000)
}) var failExample = new Promise(function(resolve, reject) {
setTimeout(function() {
reject(new Error('我错了'))
}, 1000)
})

then方法

Promise 实例具有then方法,then方法的第一个参数是resolve(成功)的回调,第二个参数(可选)是reject(失败)的回调。

var promise = new Promise(function(resolve, reject) {
setTimeout(function() {
if (false) {
resolve("我是数据")
} else {
reject(new Error('我错了'))
}
}, 1000)
}) promise.then(function(data) {
console.log(data) // 我是数据 当if条件为真时触发
}, function(err) {
console.log(err) // Error: 我错了 当if条件为假时触发
})

使用箭头函数的话,代码会更简洁:

var promise = new Promise((resolve, reject) => {
setTimeout(() => {
false ? resolve("我是数据") : reject(new Error('我错了'))
}, 1000)
}) promise.then(
(data) => console.log(data),
(err) => console.log(err)
)

catch方法

catch方法和then的第二个参数一样,用来指定reject时的回调,用法是这样:

var promise = new Promise((resolve, reject) => {
setTimeout(() => {
false ? resolve("我是数据") : reject(new Error('我错了'))
}, 1000)
})
promise
.then(
(data) => console.log(data)
)
.catch(
(err) => console.log(err)
)

all方法

Promise.all方法用于将多个 Promise 实例,包装成一个新的 Promise 实例。此方法提供了并行执行异步操作的能力,并且在所有异步操作执行完后才执行回调。举一个例子:开发中首页可能会有多个接口,如果写多个方法同时请求数据,很可能最终页面展示的时候会一块接一块显示出来就像是拼接完成的。通过Promise.all我们就可以将多个方法请求的数据同时展现出来:

var getData1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("1、接口1的数据")
}, 700)
}) var getData2 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("2、接口2的数据")
}, 100)
}) var getData3 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("3、接口3的数据")
}, 300)
}) Promise.all(
[getData1, getData2, getData3]
).then((data) => {
console.log(data) // ["1、接口1的数据", "2、接口2的数据", "3、接口3的数据"]
})

上述代码可以看出all接收一个数组作为参数,数组成员分别是定义好的Promise实例,当所有的接口都成功时将按顺序把返回的结果放到一个数组里传给then方法。

race方法

Promise.race方法同样是将多个 Promise 实例,包装成一个新的 Promise 实例。使用race方法时如果有一个率先成功,那么就立即返回。由此可见all和race的区别是: all方法的效果实际上是 “谁跑的慢,以谁为准执行回调”, race方法的效果实际上是 ”谁跑的快,以谁为准执行回调”

var getData1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("1、接口1的数据")
}, 700)
}) var getData2 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("2、接口2的数据")
}, 1000)
}) var getData3 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("3、接口3的数据")
}, 300)
})
Promise
.race(
[getData1, getData2, getData3]
)
.then((data) => {
console.log(data)// 3、接口3的数据
})

Promise的出现主要是解决地狱回调的问题,比如有一个功能需要请求很多个接口,且每一个接口的参数都需要另外一个的接口返回的数据作为依赖,这样就需要我们一层嵌套一层,但是有了Promise 我们就无需嵌套,就可以使用then方法链式调用。