说明

关于Promise的基本语法可以从ECMAScript 6 入门–Promise对象中获取。本文主要记录自己在项目中关于Promise对象的使用,并进行对象的说明。本文后续会不断补充Promise的使用场景。

使用场景

由于代码是直接摘取项目中实际使用的代码,所以可能会涉及到一些框架的知识背景。

对接口返回数据的缓存

由于请求接口是一个异步的过程,如果使用普通变量对接口的返回数据进行缓存,就会导致在程序中去访问这个变量时,这个变量可能还未得到接口返回的数据。这里我们就可以使用Promsie来很好的解决这个问题。

第一版

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public stationList: any[] = [];
public getStationList(): Promise<any[]> {
if (this.stationList.length === 0) {
return this.http
.get(`${this.apiUrl}/api/index/getSampleStationAll`)
.map(res => {
return res.json();
})
.toPromise()
.then(res => {
this.stationList = res;
return this.stationList;
});
} else {
return new Promise((resolve, reject) => {
resolve(this.stationList);
});
}
}

由于项目中多处用到电站列表,所以这里对接口返回的电站列表进行缓存。上面代码的思路是通过变量stationList来保存接口返回的数据。在代码中,我们通过getStationList().then()的方式来获取到数据。getStationList()返回一个Promise对象,通过stationList是否有数据来判断是调用接口还是new一个Promise对象将stationList数据resolve()出来.

上面的代码存在一个不足的地方,就是每次调用getStationList()都要重新实例化一个Promise对象。下面我们对代码进行改进。

第二版

1
2
3
4
5
6
7
8
9
10
11
12
13
public stationList: Promise<any[]> = null;
public getStationList(): Promise<any[]> {
if (!this.stationList) {
this.stationList = this.http
.get(`${this.apiUrl}/api/index/getSampleStationAll`)
.map(res => {
return res.json();
})
.toPromise();
}
return this.stationList;
}

这里主要的修改就是将stationList的类型改为了Promise对象。getStationList()中通过stationList是否有值来判断是直接返回stationList还是去调接口。