internal static Action NewPromiseResolveThenableJob(PromiseInstance promise, ObjectInstance thenable, ICallable thenMethod) { return(() => { var(resolve, reject) = promise.CreateResolvingFunctions(); try { thenMethod.Call(thenable, new[] { resolve as JsValue, reject }); } catch (JavaScriptException e) { reject.Call(JsValue.Undefined, new[] { e.Error }); } }); }
internal static JsValue PerformPromiseThen( Engine engine, PromiseInstance promise, JsValue onFulfilled, JsValue onRejected, PromiseCapability resultCapability) { var fulfilReaction = new PromiseReaction(ReactionType.Fulfill, resultCapability, onFulfilled); var rejectReaction = new PromiseReaction(ReactionType.Reject, resultCapability, onRejected); switch (promise.State) { case PromiseState.Pending: promise.PromiseFulfillReactions.Add(fulfilReaction); promise.PromiseRejectReactions.Add(rejectReaction); break; case PromiseState.Fulfilled: engine.AddToEventLoop(NewPromiseReactionJob(fulfilReaction, promise.Value)); break; case PromiseState.Rejected: engine.AddToEventLoop(NewPromiseReactionJob(rejectReaction, promise.Value)); break; default: ExceptionHelper.ThrowArgumentOutOfRangeException(); break; } //https://tc39.es/ecma262/#sec-performpromisethen //... //13. If resultCapability is undefined, then // a. Return undefined //14. Else // a. Return resultCapability.[[Promise]] if (resultCapability is null) { return(JsValue.Undefined); } return(resultCapability.PromiseInstance); }