CefSharp Javascript异步响应太快



我的方法是访问每个链接,如果所有链接都被访问,则从中接收返回值。问题是,当我启动代码时,我会立即得到一个响应,显然是空的,因为并不是所有的链接都被访问过。

private async void ibtn_start_visiting_Click(object sender, EventArgs e)
{
string js = "var ele = document.querySelectorAll('#profiles * .tile__link');document.getElementsByClassName('js-scrollable')[0].scrollBy(0,30);ele.forEach(function(value,index){setTimeout(function(){if(index < ele.length-1){ele[index].click();}else{document.querySelectorAll('.search-results__item').forEach(e => e.parentNode.removeChild(e));document.getElementsByClassName('js-close-spotlight')[0].click();return 'hallo';}},1000 * index)})";

await browser.EvaluateScriptAsync(js).ContinueWith(x =>
{
var response = x.Result;
if (response.Success)
{
this.Invoke((MethodInvoker)delegate
{
var res = (string)response.Result;
Console.WriteLine("Response: " + res);


});
}
else {
Console.WriteLine("NO");
}

});

}

这是javascript:

var ele = document.querySelectorAll('#profiles * .tile__link');
document.getElementsByClassName('js-scrollable')[0].scrollBy(0,30);
ele.forEach(function(value,index){
setTimeout(function(){
if(index < ele.length-1){
ele[index].click();

}
else{

document.querySelectorAll('.search-results__item').forEach(e => e.parentNode.removeChild(e));
document.getElementsByClassName('js-close-spotlight')[0].click();
alert('hallo');
}
},1500 * index)
})

哦,我明白了。您的javascript使用setTimeout,这相当于使传递给它的函数也是异步的。CefSharp不知道setTimeout任务何时完成,因此提前返回。挂起的javascript代码最终会执行。要知道什么时候完成,你有几个选择:

  1. 通过完全摆脱setTimeout,使您的异步javascript代码同步
  2. 在异步javascript代码中设置一些全局变量,并定期检查C#中的网页,看看是否设置了该变量
  3. 注册一些JS处理程序,并在异步javascript完成时调用它

#3是我的最爱,所以您可以在C#中注册该处理程序,如下所示:

public class CallbackObjectForJs{
public void showMessage(string msg){
// we did it!
}
}
webView.RegisterJsObject("callbackObj", new CallbackObjectForJs());

你的JS可能看起来像:

var totalTasks = 0;
function beginTask() {
totalTasks++;
}
function completeTask() {
totalTasks--;
if (totalTasks === 0) {
callbackObj("we finished!"); // this function was registered via C#
}
}
var ele = document.querySelectorAll('#profiles * .tile__link');
document.getElementsByClassName('js-scrollable')[0].scrollBy(0,30);
ele.forEach(function(value,index){
beginTask();  // NEW
setTimeout(function(){
... // work
completeTask();
}, 1500 * index);
})

为了更清楚,您可能需要查看Javascript的Promise.all()

最新更新