Esempio n. 1
0
        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);
        }
Esempio n. 2
0
        private static Action NewPromiseReactionJob(PromiseReaction reaction, JsValue value)
        {
            return(() =>
            {
                var promiseCapability = reaction.Capability;

                if (reaction.Handler is ICallable handler)
                {
                    try
                    {
                        var result = handler.Call(JsValue.Undefined, new[] { value });
                        promiseCapability.Resolve.Call(JsValue.Undefined, new[] { result });
                    }
                    catch (JavaScriptException e)
                    {
                        promiseCapability.Reject.Call(JsValue.Undefined, new[] { e.Error });
                    }
                }
                else
                {
                    switch (reaction.Type)
                    {
                    case ReactionType.Fulfill:
                        promiseCapability.Resolve.Call(JsValue.Undefined, new[] { value });
                        break;

                    case ReactionType.Reject:
                        promiseCapability.Reject.Call(JsValue.Undefined, new[] { value });
                        break;

                    default:
                        throw new ArgumentOutOfRangeException();
                    }
                }
            });
        }