Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

demo中并不能实现JS端异步调用原生方法 #15

Closed
mailworks opened this issue Sep 28, 2017 · 3 comments
Closed

demo中并不能实现JS端异步调用原生方法 #15

mailworks opened this issue Sep 28, 2017 · 3 comments

Comments

@mailworks
Copy link

步骤:
在JsApiTest定义JS异步调用的方法中加入阻塞线程代码,比如

- (void) testAsyn:(NSDictionary *) args :(void (^)(NSString * _Nullable result,BOOL complete))completionHandler
{
    sleep(5);
    completionHandler([(NSString *)[args valueForKey:@"msg"] stringByAppendingString:@"[ asyn call]"],YES);
}

test.html js端加上log日志

function callAsyn() {
        console.log("callAsyn beigin")
        bridge.call("testAsyn", {msg: "testAsyn"}, function (v) {
                    alert(v)
                })
        console.log("callAsyn end")
    }

在js端调用 程序时序是这样的

console.log("callAsyn beigin")
等待五秒
alert(v)
console.log("callAsyn end")

可以看出这并不是异步调用

@wendux
Copy link
Owner

wendux commented Sep 28, 2017

你native实现方式有问题,无论何时testAsyn都会被同步调用,只是completionHandler调用时才会触发js回调, sleep直接阻塞线程,所谓支持异步,是客户端的任务实现本身就要是异步的。

@wendux wendux closed this as completed Sep 28, 2017
@mailworks
Copy link
Author

mailworks commented Sep 28, 2017

相当于JS端必须同步的调Native端的方法,如果Native对应的方法耗时太多也会阻塞JS端的线程,所谓的“异步”只能在Native端方法写“异步”处理?

这样做就违背了WKWebView的设计原则了

No I don't believe it is possible due to the multi-process architecture of WKWebView. WKWebView runs in the same process as your application but it communicates with WebKit which runs in its own process (Introducing the Modern WebKit API). The JavaScript code will be running in the WebKit process. So essentially you are asking to have synchronous communication between two different processes which goes against their design

用原生的方式JS-Native异步调用和这个框架“异步”是有区别的

  [controller addScriptMessageHandler:self name:@"observe"];
- (void)userContentController:(WKUserContentController *)userContentController
      didReceiveScriptMessage:(WKScriptMessage *)message 

可以参加下这个Demo,加Native端加了sleep函数 JS端也不会block

JSMessageExample-master.zip

@wendux
Copy link
Owner

wendux commented Sep 29, 2017

Native对应的方法耗时太多的话,我觉得应该由程序员在Native进行显式的异步处理。你的这种场景,其实就是:只要js以异步方式调用,即使native端是同步处理的,对于js来说也要是异步的。这样的话如果所有异步任务,natvie端都以同步的方式来处理,同时使用messageHandler 来做,是有问题的,原因如下:WKWebView处理js消息是在一个单独的线程,如果端上还是同步的写法,那么任务多时,必定是要排队的,native端的任务就会阻塞,这会导致native端执行完所有的“异步任务”的总时长延长,因为只有一个线程。这样虽然js不会阻塞,但是native端还是会阻塞,而解决的方法还是要在MessageHandler中手动开线程。所以我认为,任务是否是异步应该接口提供方自己决定,而不是调用方。不过WKWebview中用MessageHandler的方式是好一些,职责分离,但由于目前DSBridge目前支持UIWebview,也是为了统一的行为,之后的版本可能会使用MessageHandler。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants