【问题标题】:DotNetBrowser and PromisesDotNetBrowser 和承诺
【发布时间】:2021-08-15 03:26:40
【问题描述】:

我在 .Net 应用程序中使用 DotNetBrowser 作为一种无头 Javascript 引擎。似乎 DotNetBrowser 不支持 Promises,或者我没有正确使用它们。

在 JS 中:

window.fooAsyncMethod = () => {
    return new Promise((resolve, reject) => {
        resolve('async value to resolve');
    });
}

在 C# 中:

var result = await browser.MainFrame.ExecuteJavascript("await window.fooAsyncMethod()")

在这种情况下,结果始终为空。我也尝试过 async/await,但总是收到 null:

window.fooAsyncMethod = async () => {
    return await someOtherAsyncMethod()
}

DotNetBrowser 是否支持运行异步 javascript?如果是这样,我如何才能等待异步操作的结果并在 C# 中解析该值?

【问题讨论】:

    标签: dotnetbrowser


    【解决方案1】:

    查看JS-.NET bridge examples,它似乎是does support promises,但使用起来有点复杂。

    如果您在 C# 端实现一种类型的 Promise 对象:

    public static class JsObjectExtensions
    {
        #region Methods
    
        public static JsPromise AsPromise(this IJsObject jsObject) => JsPromise.AsPromise(jsObject);
    
        #endregion
    }
    
    public sealed class JsPromise
    {
        private readonly IJsObject jsObject;
    
        #region Constructors
    
        private JsPromise(IJsObject jsObject)
        {
            this.jsObject = jsObject;
        }
    
        #endregion
    
        public static JsPromise AsPromise(IJsObject jsObject) => !IsPromise(jsObject) ? null : new JsPromise(jsObject);
    
        public JsPromise Catch(Func<object, object> onRejected)
        {
            IJsObject newPromise = jsObject.Invoke("catch", onRejected) as IJsObject;
            return new JsPromise(newPromise);
        }
    
        public Task<Result> ResolveAsync()
        {
            TaskCompletionSource<Result> promiseTcs = new TaskCompletionSource<Result>();
            Then(obj => { promiseTcs.TrySetResult(Fulfilled(obj)); },
                 obj => { promiseTcs.TrySetResult(Rejected(obj)); });
    
            promiseTcs.Task.ConfigureAwait(false);
            return promiseTcs.Task;
        }
    
        public void Then(Action<object> onFulfilled, Action<object> onRejected = null)
        {
            jsObject.Invoke("then", onFulfilled, onRejected);
        }
    
        public JsPromise Then(Func<object, object> onFulfilled, Func<object, object> onRejected = null)
        {
            IJsObject newPromise = jsObject.Invoke("then", onFulfilled, onRejected) as IJsObject;
            return new JsPromise(newPromise);
        }
    
        private Result Fulfilled(object o) => new Result(ResultState.Fulfilled, o);
    
        private static bool IsPromise(IJsObject jsObject)
        {
            if (jsObject == null || jsObject.IsDisposed)
            {
                return false;
            }
    
            IJsObject promisePrototype = jsObject.Frame.ExecuteJavaScript<IJsObject>("Promise.prototype").Result;
            return promisePrototype.Invoke<bool>("isPrototypeOf", jsObject);
        }
    
        private Result Rejected(object o) => new Result(ResultState.Rejected, o);
    
        public enum ResultState
        {
            Fulfilled,
            Rejected
        }
    
        public class Result
        {
            public object Data { get; }
            public ResultState State { get; }
    
            internal Result(ResultState state, object data)
            {
                State = state;
                Data = data;
            }
        }
    }
    

    然后你就可以像这样调用promise了:

                        IJsObject window = browser.MainFrame.ExecuteJavaScript<IJsObject>("window").Result;
                        //Prepare promise handlers
                        Action<object> promiseResolvedHandler = o => Console.WriteLine("Success: " + o);
                        Action<object> promiseRejectedHandler = o => Console.Error.WriteLine("Error: " + o);
    
                        //Create a promise that is fulfilled
                        Console.WriteLine("Create a promise that is fulfilled...");
                        IJsObject promise1 = window.Invoke<IJsObject>("CreatePromise", true);
                        //Append fulfillment and rejection handlers to the promise
                        promise1.Invoke("then", promiseResolvedHandler, promiseRejectedHandler);
    
                        //Create a promise that is rejected
                        Console.WriteLine("Create a promise that is rejected...");
                        IJsObject promise2 = window.Invoke<IJsObject>("CreatePromise", false);
                        //Append fulfillment and rejection handlers to the promise
                        promise2.Invoke("then", promiseResolvedHandler, promiseRejectedHandler);
    
                        CreatePromiseAsync(window).Wait();
    

    请注意,以上所有代码均直接取自他们的Promises Example

    【讨论】:

    • 是的,这也是我从他们的客户支持那里得到的确切回复。谢谢!
    猜你喜欢
    • 2015-05-12
    • 2023-03-26
    • 1970-01-01
    • 2015-12-30
    • 2019-05-03
    • 1970-01-01
    • 2016-03-04
    • 1970-01-01
    • 2015-10-06
    相关资源
    最近更新 更多