1/* 2 * Copyright (c) 2025 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16class StepSequence { 17 constructor(numCheckpoints: int) { 18 this.numCheckpoints = numCheckpoints; 19 this.sequence = new Array<number>(); 20 } 21 22 checkOrder() { 23 assertEQ(this.sequence.length, this.numCheckpoints, 24 "Test failed. Expected " + this.numCheckpoints + " checkpoints, but got " + this.sequence.length); 25 for (let step = 0; step < this.sequence.length; ++step) { 26 assertEQ(step, this.sequence[step], `Failed at step: ${step}. Got ${this.sequence[step]}`); 27 } 28 } 29 30 checkpoint(value: int) { 31 this.sequence.push(value); 32 } 33 34 private sequence: Array<number>; 35 private numCheckpoints: int; 36} 37 38let executionOrder = new StepSequence(0); 39let promiseIsPending: boolean 40 41async function foo() { 42 executionOrder.checkpoint(1); 43 let p = bar(); 44 executionOrder.checkpoint(3); 45 return p; 46} 47 48async function bar() { 49 executionOrder.checkpoint(2); 50 let emptyBody = () => { return 0; }; 51 promiseIsPending ? launch<Int, () => Int>(emptyBody).Await() 52 : await Promise.resolve(0); 53 executionOrder.checkpoint(5); 54} 55 56function executionOrderTest(isPending: boolean) { 57 executionOrder = new StepSequence(6); 58 promiseIsPending = isPending; 59 executionOrder.checkpoint(0); 60 let p = foo(); 61 executionOrder.checkpoint(4); 62 await p; 63 executionOrder.checkOrder(); 64} 65 66function testWithPendingPromise() { 67 executionOrderTest(true); 68} 69 70function testWithResolvedPromise() { 71 executionOrderTest(false); 72} 73 74function testPromiseBeforeAsync() { 75 executionOrder = new StepSequence(4); 76 let af = async () => { 77 executionOrder.checkpoint(0); 78 await Promise.resolve<Int>(0); 79 executionOrder.checkpoint(3); 80 }; 81 Promise.resolve<Int>(0).then(() => { 82 executionOrder.checkpoint(2); 83 }); 84 let p = af(); 85 executionOrder.checkpoint(1); 86 await p; 87 executionOrder.checkOrder(); 88} 89 90async function dealPromise(asyncThen: boolean) { 91 const p: Promise<string> = new Promise<string>((resolve, reject) => { 92 resolve("resolve"); 93 executionOrder.checkpoint(0); 94 }); 95 if (asyncThen) { 96 p.then(async (res: string) => { 97 executionOrder.checkpoint(2); 98 await Promise.resolve(); 99 executionOrder.checkpoint(4); 100 }); 101 } else { 102 p.then((res: string) => { 103 executionOrder.checkpoint(2); 104 }); 105 } 106 executionOrder.checkpoint(1); 107} 108 109function testWithPromiseThen() { 110 executionOrder = new StepSequence(4); 111 let af = async () => { 112 await dealPromise(false); 113 executionOrder.checkpoint(3); 114 } 115 await af(); 116 executionOrder.checkOrder(); 117} 118 119function testWithAsyncPromiseThen() { 120 executionOrder = new StepSequence(6); 121 let af = async () => { 122 await dealPromise(true); 123 executionOrder.checkpoint(3) 124 } 125 await af().then((): void => { 126 executionOrder.checkpoint(5) 127 }); 128 executionOrder.checkOrder(); 129} 130 131 132function main() { 133 testWithPendingPromise(); 134 testWithResolvedPromise(); 135 testPromiseBeforeAsync(); 136 testWithPromiseThen(); 137 testWithAsyncPromiseThen(); 138} 139