一、概述
自己对Promise的理解仅仅停留在他是一个异步请求后台接口的处理方式上,突然看到有些没有请求后台接口的函数也使用到了Promise,顿时感到非常疑惑,于是强补下这方面的知识。
二、主要使用方法
2.1 异步请求后台接口的后续处理
此种方式是我项目中最常用使用到Promise的场景了,伪代码如下:
// 定义一个页面初始化的方法
function initPage() {
let params = {
param1: 'data1',
param2: 'data2'
}
httpPost('http://www.test.com/', params)
.then(data => {
console.log(data)
}).catch(error => {
console.log(error)
})
}
其中httpPost的定义如下,基于axios进行了简单的封装:
function httpPost(url, data) {
return new Promise((resolve, reject) => {
axios.post(url, data)
.then((res)=>{
resolve(res)
}).catch(error => {
reject(error)
})
})
}
两个代码片段中,代码片段1的then对应代码片段2中的resolve,catch对应reject。
这里有一个经验,定义一个Promise的对象的时候,函数返回它。如上httpPost中就返回了一个Promise对象。
2.2 优雅的写法-链式操作
2.2.1 传统写法
在Promise出现之前,处理两个异步操作可能如下:
// 假设 doSomething1和doSomething2是异步的方法
// 再doSomething1之后才能开始doSomething2的操作
doSomething1(function(callbackData){
console.log('process doSometing1 callback')
doSomething2(function(callbackData) {
console.log('process doSometing2 callback')
}
})
如果有很多个数据请求都需要依赖前面一个请求,这种嵌套就很多,在我经历的项目中,可能有5-6层这种嵌套调用,缩进就很多,看起来不太优雅。
2.2.2 链式写法
下面使用两个setTimeout来模拟异步,体验下链式操作。
// 2秒后执行
function doSomething1() {
return new Promise((resolve, reject) => {
setTimeout(()=> {
console.log('doSomething1')
resolve('doSomething1 complete')
}, 2000)
})
}
// 0.2秒收执行
function doSomething2() {
return new Promise((resolve, reject) => {
setTimeout(()=> {
console.log('doSomething2')
resolve('doSomething2 complete')
}, 200)
})
}
doSomething1().then(res=>{
return doSomething2()
})
从执行结果来看,先完成了doSomething1,再执行doSomething2。
2.3 处理推迟
Promise的resolve和reject方法推迟了对函数请求的结果处理,当函数实际被调用的时候,再根据内部定义的返回进行对应的处理。从我自己的项目经验来看,Promise一般是在封装在基础功能里面,不涉及业务。
三、总结
Promise目前项目中主要用于封装基础组件,对于一些通用的业务组件,通过这次复习,也会逐渐尝试使用,减少冗余代码。