硒和异步JavaScript调用

spc*_*ial 6 javascript selenium asynchronous function callback

我对Selenium和JavaScript回调函数还很陌生,但有一个大问题我无法解决。我需要使用JavaScript的指定变量。如果我使用GoogleChrome打开页面并使用控制台输入我的JavaScript代码,则可以使用类似以下内容的变量:

1. var myId;
2. getSomeIdStuffInfo("somestuff",function(docId)(myId = docId));
3. return myId;
Run Code Online (Sandbox Code Playgroud)

如果我逐步输入此行,则很容易获得正确的值myId。但是,当然,如果我尽可能快地执行这三行,我将获得null作为返回值,因为当我返回myId时回调函数并未完成。SOOOO ..如果我像这样使用硒:

JavascriptExecutor js = (JavascriptExecutor) driver; 
    String docInfoVal = (String) js.executeScript("" +
            "var myId; " +
            "getCurrentDocumentInfo(\"somestuff\"," +
                "function(docId) {" +
                    "myId = docId;" +
                "}" +
            ");" +
            "return myId;");
Run Code Online (Sandbox Code Playgroud)

我只会得到null作为结果。所以...以某种方式我必须“等待”回调函数,直到我返回myId。我必须使用executeAsyncScript吗?我坐在上面几个小时,尝试了不同的方法,但是我找不到答案。

在此先感谢您的帮助!

Lou*_*uis 6

对于异步代码,您必须使用executeAsyncScript

JavascriptExecutor js = (JavascriptExecutor) driver; 
String docInfoVal = (String) js.executeAsyncScript("" +
        "var done = arguments[0]; " +
        "getCurrentDocumentInfo(\"somestuff\"," +
            "function(docId) {" +
                "done(docId);" +
            "}" +
        ");");
Run Code Online (Sandbox Code Playgroud)

executeAsyncScript用来调用的脚本将有一个回调添加到传递给它的参数列表中。由于您没有向脚本传递任何参数,因此arguments[0]包含了回调。完成工作后,您的代码必须调用此回调。您提供给回调的值是executeAsyncScript返回的值。

在上面的代码中,我done通过将其放在匿名函数中来阐明了对它的调用,但是代码可以更简洁地编写为:

JavascriptExecutor js = (JavascriptExecutor) driver; 
String docInfoVal = (String) js.executeAsyncScript("" +
        "var done = arguments[0]; " +
        "getCurrentDocumentInfo(\"somestuff\", done);");
Run Code Online (Sandbox Code Playgroud)

甚至:

JavascriptExecutor js = (JavascriptExecutor) driver; 
String docInfoVal = (String) js.executeAsyncScript(
        "getCurrentDocumentInfo('somestuff', arguments[0]);");
Run Code Online (Sandbox Code Playgroud)