微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

DotNetBrowser 和 Promises

如何解决DotNetBrowser 和 Promises

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

在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# 中解析该值?

解决方法

查看 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",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",promiseRejectedHandler);

                    CreatePromiseAsync(window).Wait();

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?