kingBook

导航

TypeScript async、 await、Promise

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/async_function
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/await
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Using_promises

实现延时:
// LayaAir3.x 中测试
const { regClass, property } = Laya;

@regClass()
export class Test extends Laya.Script {

    onStart() {
        this.delay(1000);
        // 先输出1,1秒后输出2
        // 输出: 
        // 1
        // 2 
    }
    
    private sleep(ms: number): Promise<any> {
        return new Promise(resolve => setTimeout(resolve, ms));
    }

    private async delay(ms: number): Promise<any> {
        console.log("1");
        await this.sleep(ms);
        console.log("2");
    }
    
}
延时执行 for循环:
// LayaAir3.x 中测试
const { regClass, property } = Laya;

@regClass()
export class Test extends Laya.Script {

    onStart() {
        this.handler(1000);
        // 输出 
        // start
        // 一秒后
        // 0
        // 一秒后
        // 1 
        // 一秒后
        // 2
        // end
    }

    private sleep(ms: number): Promise<any> {
        return new Promise(resolve => setTimeout(resolve, ms));
    }

    private async handler(ms:number): Promise<any> {
        console.log("start");
        for (let i = 0; i < 3; i++) {
            await this.sleep(ms);
            console.log(i);
        }
        console.log("end");
    }
    
}
Promise

例:使用 Promise 代替传参式的完成回调

// LayaAir3.x 中测试
const { regClass, property } = Laya;

@regClass()
export class TestPromise extends Laya.Script {

    public onAwake(): void {
        console.log("start");
        this.delay().then((value: any) => {
            console.log("end", value);
        });

        /*output: 
        start
        ...3秒后...
        end hello
        */
    }

    private delay(): Promise<any> {
        return new Promise((resolve: (value: any) => void, reject: (reason?: any) => void) => {
            setTimeout(() => {
                resolve("hello");
            }, 3000);
        });
    }

}

多个缓动

// LayaAir3.x 中测试
const { regClass, property } = Laya;

@regClass()
export class TestPromiseTweenComplete extends Laya.Script {

    public onAwake(): void {
        this.startTween();
        /*output:
        a
        // ...1秒后...
        b
        // ...1秒后...
        c
        */
    }

    private async startTween(): Promise<any> {
        console.log("a");
        await this.tween0();
        console.log("b");
        await this.tween1();
        console.log("c");
    }

    private tween0(): Promise<any> {
        return new Promise((resolve: (value: any) => void, reject: (reason?: any) => void) => {
            Laya.Tween.create(this.owner).duration(1000).to("x", 100).then(tweener => {
                resolve(tweener);
            }, this);
        });

    }

    private tween1(): Promise<any> {
        return new Promise((resolve: (value: any) => void, reject: (reason?: any) => void) => {
            Laya.Tween.create(this.owner).duration(1000).to("y", 100).then(tweener => {
                resolve(tweener);
            }, this);
        });

    }
}

Promise在TypeScript中是一个对象,它代表了一个异步操作的最终结果。一个Promise对象可以处于以下三种状态之一:
Pending(进行中): 初始状态,既不是成功,也不是失败状态。
Fulfilled(已成功): 意味着操作成功完成。
Rejected(已失败): 意味着操作失败。

// 缺省变量的类型,any 根据调用 resolve, reject 时传入的参数的类型进行变化
// promise: Promise<any>
// resolve: (value: any) => void
// reject: (reason?: any) => void

// 创建一个新的Promise对象
let promise = new Promise((resolve, reject) => {
    // 异步操作的代码
    if (/* 异步操作成功 */) {
        resolve(value); // 成功时调用resolve函数
    } else {
        reject(error); // 失败时调用reject函数
    }
});
Promise 的错误处理

通过.then()方法,可以指定fulfilled状态和rejected状态的回调函数,这些回调函数可以返回一个新的Promise,从而形成链式调用。

promise.then((value) => {
    // 成功时执行的代码
}).catch((error) => {
    // 失败时执行的代码
});
promise.then((value) => {
    throw new Error('Something went wrong');
}).catch((error) => {
    // 捕获前面.then()中抛出的错误
});
Promise的静态方法

Promise还提供了一些静态方法,如Promise.all()和Promise.race(),它们可以用于处理多个Promise的组合.

// 等待所有Promise完成
Promise.all([promise1, promise2]).then((values) => {
    // 所有Promise都成功时执行的代码
});

// 竞赛,哪个Promise先完成就使用哪个Promise的结果
Promise.race([promise1, promise2]).then((value) => {
    // 最先完成的Promise的结果
});
Promise的类型推断
// TypeScript能够推断出res的类型为number
Promise.resolve(123).then((res) => {
    // res的类型被推断为number
});
Promise 返回值测试
// LayaAir3.x 中测试
const { regClass, property } = Laya;

@regClass()
export class TestPromiseReturn extends Laya.Script {


    private resolvePromise(): Promise<any> {
        return new Promise((resolve: (value: any) => void, reject: (reason?: any) => void) => {
            setTimeout(() => {
                resolve("resolve promise");
            }, 1000);
        });
    }


    private rejectPromise(): Promise<any> {
        return new Promise((resolve: (value: any) => void, reject: (reason?: any) => void) => {
            setTimeout(() => {
                reject("reject promise");
            }, 1000);
        });
    }

    public onAwake(): void {
        const pa = this.resolvePromise();
        const pb = this.resolvePromise().then();
        const pc = this.resolvePromise().catch();
        console.log("pa", pa);
        console.log("pb", pb);
        console.log("pc", pc);
        /* output:
        pa Promise {<pending>}[[Prototype]]: Promise[[PromiseState]]: "fulfilled"[[PromiseResult]]: "resolve promise"
        pb Promise {<pending>}[[Prototype]]: Promise[[PromiseState]]: "fulfilled"[[PromiseResult]]: "resolve promise"
        pc Promise {<pending>}[[Prototype]]: Promise[[PromiseState]]: "fulfilled"[[PromiseResult]]: "resolve promise"
        */

        const pb1 = this.resolvePromise().then(res => { });
        const pb2 = this.resolvePromise().then(res => { }, err => { });
        const pb3 = this.resolvePromise().then(res => { }, err => { return err; });
        console.log("pb1", pb1);
        console.log("pb2", pb2);
        console.log("pb3", pb3);
        /* output:
       pb1 Promise[[Prototype]]: Promise[[PromiseState]]: "fulfilled"[[PromiseResult]]: undefined
       pb2 Promise[[Prototype]]: Promise[[PromiseState]]: "fulfilled"[[PromiseResult]]: undefined
       pb3 Promise[[Prototype]]: Promise[[PromiseState]]: "fulfilled"[[PromiseResult]]: undefined
       */

        const pb4 = this.resolvePromise().then(res => { return res; });
        const pb5 = this.resolvePromise().then(res => { return res; }, err => { });
        const pb6 = this.resolvePromise().then(res => { return res; }, err => { return err; });
        console.log("pb4", pb4);
        console.log("pb5", pb5);
        console.log("pb6", pb6);
        /* output:
        pb4 Promise[[Prototype]]: Promise[[PromiseState]]: "fulfilled"[[PromiseResult]]: "resolve promise"
        pb5 Promise[[Prototype]]: Promise[[PromiseState]]: "fulfilled"[[PromiseResult]]: "resolve promise"
        pb6 Promise[[Prototype]]: Promise[[PromiseState]]: "fulfilled"[[PromiseResult]]: "resolve promise"
        */
    }

    public onEnable(): void {
        const p1 = this.rejectPromise();
        const p2 = this.rejectPromise().then();
        const p3 = this.rejectPromise().catch();
        console.log("p1", p1);
        console.log("p2", p2);
        console.log("p3", p3);
        /* output:
        p1 Promise {<pending>}[[Prototype]]: Promise[[PromiseState]]: "rejected"[[PromiseResult]]: "reject promise"
        p2 Promise {<pending>}[[Prototype]]: Promise[[PromiseState]]: "rejected"[[PromiseResult]]: "reject promise"
        p3 Promise {<pending>}[[Prototype]]: Promise[[PromiseState]]: "rejected"[[PromiseResult]]: "reject promise"
        */

        const p11 = this.rejectPromise().then(res => { }, err => { });
        const p22 = this.rejectPromise().then(res => { }, err => { return err; });
        console.log("p11", p11);
        console.log("p22", p22);
        /* output:
        p11 Promise {<pending>}[[Prototype]]: Promise[[PromiseState]]: "fulfilled"[[PromiseResult]]: undefined
        p22 Promise {<pending>}[[Prototype]]: Promise[[PromiseState]]: "fulfilled"[[PromiseResult]]: "reject promise"
        */

        const p33 = this.rejectPromise().catch(err => { });
        const p44 = this.rejectPromise().catch(err => { return err; });
        console.log("p33", p33);
        console.log("p44", p44);
        /* output:
        p33 Promise {<pending>}[[Prototype]]: Promise[[PromiseState]]: "fulfilled"[[PromiseResult]]: undefined
        p44 Promise {<pending>}[[Prototype]]: Promise[[PromiseState]]: "fulfilled"[[PromiseResult]]: "reject promise"
        */
    }

    public onStart(): void {
        this.resolvePromise().then(res => { }).then(res => { console.log("res", res); });             // 1秒后,输出:res undefined
        this.resolvePromise().then(res => { return res; }).then(res => { console.log("res", res); }); // 1秒后,输出:res resolve promise

        this.rejectPromise()
            .then(res => { return res; }, err => { }) // 定义了 onrejected 回调,在赋值到变量或链式调用时,将不再被执行
            .then(res => { return res; }, err => { console.log("err0", err); }); // 无输出

        this.rejectPromise()
            .then(res => { return res; }, err => { return err; }) // 定义了 onrejected 回调,在赋值到变量或链式调用时,将不再被执行
            .then(res => { return res; }, err => { console.log("err1", err); }); // 无输出

        this.rejectPromise()
            .then(res => { return res; }) // 
            .then(res => { return res; }, err => { console.log("err2", err); }); // 1秒后,输出:err2 reject promise

        this.rejectPromise().catch().catch(err => { console.log("err3", err); }); // 1秒后,输出:err3 reject promise

        this.rejectPromise()
            .catch(err => { }) // 定义了 onrejected 回调,在赋值到变量或链式调用时,将不再被执行
            .catch(err => { console.log("err4", err); }); // 无输出
        this.rejectPromise()
            .catch(err => { return err; }) // 定义了 onrejected 回调,在赋值到变量或链式调用时,将不再被执行
            .catch(err => { console.log("err5", err); }); // 无输出
    }

}
Promise await 返回值测试
// LayaAir3.x 中测试
const { regClass, property } = Laya;

@regClass()
export class TestPromiseAwaitReturn extends Laya.Script {

    public createSpriteAsync(): Promise<Laya.Sprite> {
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                const sprite = new Laya.Sprite();
                resolve(sprite);
            }, 1000);
        });
    }

    public createSpriteAsyncErr(): Promise<Laya.Sprite> {
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                reject(new Error("create sprite error"));
            }, 1000);
        });
    }


    public async onAwake() {
        const promise: Promise<Laya.Sprite> = this.createSpriteAsync();
        console.log("promise:", promise); // promise: Promise {<pending>}[[Prototype]]: Promise[[PromiseState]]: "fulfilled"[[PromiseResult]]: Sprite

        const sprite: Laya.Sprite = await this.createSpriteAsync();
        console.log("sprite:", sprite); // 1秒后,输出:sprite: Sprite {_bits: 9, _reactiveBits: 16, _hideFlags: 0, _parent: null, _destroyed: false, …}


        const promise1: Promise<Laya.Sprite> = this.createSpriteAsyncErr();
        console.log("promise1:", promise1); // promise1: Promise {<pending>}[[Prototype]]: Promise[[PromiseState]]: "rejected"[[PromiseResult]]: Error: create sprite error at ...

        const sprite1: Laya.Sprite = await this.createSpriteAsyncErr();
        // 因报错而中止,此处以下的所有代码不会执行
        console.log("sprite1:", sprite1);
    }

}

posted on 2025-04-29 00:23  kingBook  阅读(47)  评论(0)    收藏  举报