有时候当我们需要等待一些异步操作执行结束再去做一些事情的时候通常使用Promise就可以做到,如下
public async main(){
console.log("开始执行,等待3000ms")
await this.waitComplete(3000)
console.log("等待结束")
}
public async waitComplete(time){
let promise = new Promise((resolve, reject) => {
setTimeout(()=>{
resolve()
}, time)
})
return promise
}
我们输出第一个log之后,传入了3000ms打开了计时器,此时,代码会停在这里,直到计时器运行结束后调用resolve后设置promise完成,才会往下继续执行
这样就完成了等待异步的操作,但是我们发现 Promise 和定时器耦合在一起,也就是说定时器必须写在 Promise 里面,因为需要等待定时器完成修改 Promise 的状态。接下来解耦,我们希望外部能控制 Promise 的状态
这时候就要用到Deferred了,为此,我们实现了如下代码:
export class Deferred {
private _resolve: () => void;
private _reject: () => void;
private _promise: Promise<void>
constructor() {
this._promise = new Promise<void>((resolve, reject) => {
this._resolve = resolve
this._reject = reject
})
}
public get promise(): Promise<void> {
return this._promise;
}
public resolve() {
this._resolve()
}
public reject(): void {
this._reject()
}
}
你会发现,其实也就是将Promise简单封装起来了,这个时候就能在外部控制promise了,正常用法如下
public async main(){
await this.load()
console.log("加载完成")
}
public load(): Promise<void>{
let deferred = new Deferred();
this.loadAsset(()=>{
deferred.resolve()
})
return deferred.promise
}
public loadAsset(callback) {
callback()
}
如果你想在多个地方想控制1个 Promise 的状态,只要有其中一个完成就完成等待(相当于或)
public async main(){
await this.load()
console.log("完成,只会回调一次")
}
public load(): Promise<void>{
let deferred = new Deferred();
setTimeout(()=>{
deferred.resolve()
}, 3000)
setTimeout(()=>{
deferred.resolve()
}, 2000)
return deferred.promise
}
如果你想在多个地方想控制1个 Promise 的状态,当全部完成时完成等待,往下执行(相当于且)
public async main(){
await this.load()
console.log("全部完成")
}
public load(): Promise<void>{
let deferred1 = new Deferred();
let deferred2 = new Deferred();
this.loadAsset(()=>{
deferred1.resolve()
})
this.loadAsset(()=>{
deferred2.resolve()
})
return Promise.all([deferred1.promise, deferred2.promise])
}
public loadAsset(callback){
callback()
}