fulfillment-order.js (2685B)
1 // |reftest| module async 2 // Copyright (C) 2025 Igalia, S.L. All rights reserved. 3 // This code is governed by the BSD license found in the LICENSE file. 4 /*--- 5 esid: sec-async-module-execution-fulfilled 6 description: > 7 When an async module fulfills, the promises relative to itself and its ancestors are resolved in leaf-to-root order 8 info: | 9 AsyncModuleExecutionFulfilled ( module ) 10 ... 11 7. If module.[[TopLevelCapability]] is not empty, then 12 a. Assert: module.[[CycleRoot]] and module are the same Module Record. 13 b. Perform ! Call(module.[[TopLevelCapability]].[[Resolve]], undefined, « undefined »). 14 8. Let execList be a new empty List. 15 9. Perform GatherAvailableAncestors(module, execList). 16 10. Assert: All elements of execList have their [[AsyncEvaluationOrder]] field set to an integer, [[PendingAsyncDependencies]] field set to 0, and [[EvaluationError]] field set to empty. 17 11. Let sortedExecList be a List whose elements are the elements of execList, sorted by their [[AsyncEvaluationOrder]] field in ascending order. 18 12. For each Cyclic Module Record m of sortedExecList, do 19 a. If m.[[Status]] is evaluated, then 20 i. Assert: m.[[EvaluationError]] is not empty. 21 b. Else if m.[[HasTLA]] is true, then 22 i. Perform ExecuteAsyncModule(m). 23 c. Else, 24 i. Let result be m.ExecuteModule(). 25 ii. If result is an abrupt completion, then 26 1. Perform AsyncModuleExecutionRejected(m, result.[[Value]]). 27 iii. Else, 28 1. Set m.[[AsyncEvaluationOrder]] to done. 29 2. Set m.[[Status]] to evaluated. 30 3. If m.[[TopLevelCapability]] is not empty, then 31 a. Assert: m.[[CycleRoot]] and m are the same Module Record. 32 b. Perform ! Call(m.[[TopLevelCapability]].[[Resolve]], undefined, « undefined »). 33 flags: [module, async] 34 features: [top-level-await, promise-with-resolvers] 35 includes: [compareArray.js] 36 ---*/ 37 38 import { p1, pA_start, pB_start } from "./fulfillment-order_setup_FIXTURE.js"; 39 40 let logs = []; 41 42 const importsP = Promise.all([ 43 // Ensure that a.Evaluate() is called after b.Evaluate() 44 pB_start.promise.then(() => import("./fulfillment-order_a_FIXTURE.js").finally(() => logs.push("A"))).catch(() => {}), 45 import("./fulfillment-order_b_FIXTURE.js").finally(() => logs.push("B")).catch(() => {}), 46 ]); 47 48 // Wait for evaluation of both graphs with entry points in A and B to start before 49 // settling the promise that B is blocked on. 50 Promise.all([pA_start.promise, pB_start.promise]).then(p1.resolve); 51 52 importsP.then(() => { 53 assert.compareArray(logs, ["B", "A"]); 54 55 $DONE(); 56 });