/// <summary> /// Creates a new Promise instance. /// </summary> /// <param name="prototype"></param> /// <param name="executor"></param> internal PromiseInstance(ObjectInstance prototype, FunctionInstance executor) : base(prototype) { FunctionInstance resolveFunc = new ClrStubFunction(Engine.FunctionInstancePrototype, (engine, thisObj, param) => { this.state = PromiseState.Fulfilled; if (param.Length > 0) { result = param[0]; } return(Undefined.Value); }); FunctionInstance rejectFunc = new ClrStubFunction(Engine.FunctionInstancePrototype, (engine, thisObj, param) => { this.state = PromiseState.Rejected; if (param.Length > 0) { result = param[0]; } return(Undefined.Value); }); try { executor.Call(Undefined.Value, resolveFunc, rejectFunc); } catch (JavaScriptException ex) { rejectFunc.Call(Undefined.Value, ex.ErrorObject); } }
public PromiseInstance Reject(object reason) { ClrStubFunction func = new ClrStubFunction(this.Engine.FunctionInstancePrototype, (engine, thisObj, args) => { FunctionInstance resolve = (FunctionInstance)args[0]; FunctionInstance reject = (FunctionInstance)args[1]; reject.Call(thisObj, reason); return(Undefined.Value); }); return(this.Construct(func)); }
public PromiseInstance Then(object onFulfilled, object onRejected) { // Get the @@species constructor, if one exists. var constructor = TypeUtilities.GetSpeciesConstructor(this, Engine.Promise); // Create a new promise instance. var executor = new ClrStubFunction(Engine.FunctionInstancePrototype, "", 2, (engine, thisObj, args) => Undefined.Value); var result = constructor.ConstructLateBound(constructor, executor); if (result is PromiseInstance resultPromise) { return(PerformPromiseThen(onFulfilled as FunctionInstance, onRejected as FunctionInstance, resultPromise)); } throw new JavaScriptException(ErrorType.TypeError, "Subclassed promises are not supported."); }
/// <summary> /// Creates a new Promise instance. /// </summary> /// <param name="prototype"></param> /// <param name="executor"></param> internal PromiseInstance(ObjectInstance prototype, FunctionInstance executor) : base(prototype) { FunctionInstance resolveFunc = new ClrStubFunction(Engine.FunctionInstancePrototype, (engine, thisObj, param) => { return(Undefined.Value); }); FunctionInstance rejectFunc = new ClrStubFunction(Engine.FunctionInstancePrototype, (engine, thisObj, param) => { return(Undefined.Value); }); try { executor.Call(Undefined.Value, resolveFunc, rejectFunc); } catch (JavaScriptException ex) { rejectFunc.Call(Undefined.Value, ex.ErrorObject); } }
/// <summary> /// Creates a new Promise instance. /// </summary> /// <param name="prototype"></param> /// <param name="executor"></param> internal PromiseInstance(ObjectInstance prototype, FunctionInstance executor) : base(prototype) { FunctionInstance resolveFunc = new ClrStubFunction(Engine.FunctionInstancePrototype, (engine, thisObj, param) => { return Undefined.Value; }); FunctionInstance rejectFunc = new ClrStubFunction(Engine.FunctionInstancePrototype, (engine, thisObj, param) => { return Undefined.Value; }); try { executor.Call(Undefined.Value, resolveFunc, rejectFunc); } catch (JavaScriptException ex) { rejectFunc.Call(Undefined.Value, ex.ErrorObject); } }
public PromiseInstance All(ObjectInstance iterable) { if (iterable == null) { throw new JavaScriptException(iterable.Engine, ErrorType.TypeError, "The parameter must be an iterable."); } var iterator = TypeUtilities.GetIterator(iterable.Engine, iterable); var promises = TypeUtilities.Iterate(iterator.Engine, iterator).ToList(); var results = Engine.Array.Construct(new object[promises.Count]); var count = promises.Count; var promise = new PromiseInstance(iterable.Engine.Promise.InstancePrototype); // The promise is resolved immediately if the iterable is empty. if (promises.Count == 0) { promise.Resolve(results); return(promise); } for (var i = 0; i < promises.Count; i++) { if (promise.State != PromiseState.Pending) { break; } if (promises[i] is PromiseInstance p) { if (p.State == PromiseState.Rejected) { promise.Reject(p.Result); break; } else if (p.State == PromiseState.Fulfilled) { results[i] = p.Result; if (--count == 0) { promise.Resolve(results); break; } continue; } var j = i; // Some C# versions need this. p.Then(new ClrStubFunction(Engine.FunctionInstancePrototype, "", 1, (engine, thisObj, args) => { if (promise.State != PromiseState.Pending) { return(Undefined.Value); } results[j] = args[0]; if (--count == 0) { promise.Resolve(results); } return(Undefined.Value); }), new ClrStubFunction(Engine.FunctionInstancePrototype, "", 1, (engine, thisObj, args) => { promise.Reject(args[0]); return(Undefined.Value); })); continue; } else if (promises[i] is ObjectInstance obj && obj.HasProperty("then")) { FunctionInstance then; try { then = obj.GetPropertyValue("then") as FunctionInstance; } catch (JavaScriptException jex) { promise.Reject(jex.ErrorObject); break; } if (then != null) { try { var j = i; // Some C# versions need this. var resolve = new ClrStubFunction(iterable.Engine.Function.InstancePrototype, (engine, ths, arg) => { if (promise.State != PromiseState.Pending) { return(Undefined.Value); } results[j] = arg.Length == 0 ? Undefined.Value : arg[0]; if (--count == 0) { promise.Resolve(results); } return(Undefined.Value); }); then.Call(obj, resolve, promise.RejectFunction); continue; } catch (JavaScriptException jex) { promise.Reject(jex.ErrorObject); break; } } } results[i] = promises[i]; if (--count == 0) { promise.Resolve(results); break; } } return(promise); }
/// <summary> /// Initializes a single deprecated property. /// </summary> /// <param name="properties"> The list to add to. </param> /// <param name="propertyName"> The name of the property. </param> /// <param name="getter"> The property getter. </param> /// <param name="attributes"> The property attributes (determines whether the property is enumerable). </param> private void AddDeprecatedProperty(List<PropertyNameAndValue> properties, string propertyName, Func<ScriptEngine, object, object[], object> getter, PropertyAttributes attributes) { var getterFunction = new ClrStubFunction(this.Engine.Function.InstancePrototype, getter); properties.Add(new PropertyNameAndValue(propertyName, new PropertyDescriptor(new PropertyAccessorValue(getterFunction, null), attributes))); }
/// <summary> /// Initializes a single deprecated property. /// </summary> /// <param name="properties"> The list to add to. </param> /// <param name="propertyName"> The name of the property. </param> /// <param name="getter"> The property getter. </param> /// <param name="attributes"> The property attributes (determines whether the property is enumerable). </param> private void AddDeprecatedProperty(List <PropertyNameAndValue> properties, string propertyName, Func <ScriptEngine, object, object[], object> getter, PropertyAttributes attributes) { var getterFunction = new ClrStubFunction(this.Engine.Function.InstancePrototype, getter); properties.Add(new PropertyNameAndValue(propertyName, new PropertyDescriptor(new PropertyAccessorValue(getterFunction, null), attributes))); }
public PromiseInstance Resolve(object x) { ClrStubFunction func = new ClrStubFunction(this.Engine.FunctionInstancePrototype, (engine, thisObj, args) => { FunctionInstance resolve = (FunctionInstance)args[0]; FunctionInstance reject = (FunctionInstance)args[1]; resolve.Call(thisObj, x); return Undefined.Value; }); return this.Construct(func); }