如何通过executeAsyncScript回调函数获取Promise返回值?WebDriver技术求助
Hey there, let's work through this WebDriver + JS Promise issue together! It sounds like the core problem is how you're handling the asynchronous Promise returned by Evaluator.runScan()—setting arbitrary timeouts won't fix it if WebDriver isn't properly waiting for the Promise to resolve. Here are the key fixes and checks to try:
1. Use executeAsyncScript instead of executeScript
The biggest mistake people make here is using the wrong WebDriver method. executeScript will return immediately with the Promise object itself, not wait for it to resolve. Instead, you need executeAsyncScript—it’s designed to wait for asynchronous operations like Promises (or explicit callbacks) to complete.
Wrap your call in an async function with await to ensure WebDriver waits for the Promise to resolve:
// Java code example String scanScript = "return (async function() { return await Evaluator.runScan(); })();"; Object scanResult = ((JavascriptExecutor) driver).executeAsyncScript(scanScript);
2. Set the correct timeout type
If you’ve been setting page load timeouts or general script timeouts, those won’t apply to executeAsyncScript. You need to set the script timeout specifically for async operations:
driver.manage().timeouts().setScriptTimeout(Duration.ofMinutes(5));
This tells WebDriver to wait up to 5 minutes for the Promise (or callback) to finish before timing out.
3. Check if the Promise is actually resolving (or failing silently)
Sometimes the issue isn’t waiting time—it’s that the Promise never resolves, or rejects without you noticing. Add error handling to your JS to catch and return any issues:
String scanScriptWithErrorHandling = "return (async function() { " + "try { return await Evaluator.runScan(); } " + "catch(e) { console.error('Scan failed:', e); return 'ERROR: ' + e.message; } " + "})();"; Object result = ((JavascriptExecutor) driver).executeAsyncScript(scanScriptWithErrorHandling); System.out.println("Scan result: " + result);
This will print out any errors that might be blocking the Promise from resolving.
4. Ensure the Evaluator object is fully loaded
Before calling runScan(), make sure the Evaluator JS object exists on the page. If it’s loaded dynamically, you’ll need to wait for it first:
// Wait for Evaluator and runScan to be available new WebDriverWait(driver, Duration.ofMinutes(1)).until( webDriver -> (Boolean) ((JavascriptExecutor) webDriver).executeScript( "return typeof Evaluator !== 'undefined' && typeof Evaluator.runScan === 'function';" ) );
If you skip this step, you might be calling runScan() before the object is ready, leading to silent failures or unresolved Promises.
5. Fallback: Use explicit callbacks (if async/await isn’t working)
If for some reason async/await isn’t an option, you can manually trigger WebDriver’s callback when the Promise resolves. WebDriver automatically passes a callback function as the last argument to executeAsyncScript:
String callbackScript = "var done = arguments[arguments.length - 1]; " + "Evaluator.runScan() " + ".then(result => done(result)) " + ".catch(error => done('ERROR: ' + error.message));"; Object result = ((JavascriptExecutor) driver).executeAsyncScript(callbackScript);
This tells WebDriver to wait until you call the done callback, which happens when the Promise resolves or rejects.
Start with step 1 and 2—switching to executeAsyncScript and setting the correct timeout is the most common fix for this issue. If that doesn’t work, use the error handling in step 3 to uncover what’s blocking the Promise.
内容的提问来源于stack exchange,提问作者Wang Shuai

