c# - 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 代码最终会执行。要知道何时完成,您有几个选择:
- 通过完全摆脱来使您的异步 javascript 代码同步
setTimeout
。 - 在您的异步 javascript 代码中设置一些全局变量,并定期在 C# 中检查您的网页以查看是否设置了该变量。
- 注册一些 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()
.
推荐阅读
- r - 将 RGB 颜色转换为 DMC 牙线颜色
- python - 如何用熊猫转置完整文件
- c# - 为什么找不到我的 ResourceDictionary xaml 文件?
- time-complexity - 运行时间复杂度为 n+ (n-1) + (n-2) 。. . . (2) + (1)
- python - 如何在python中同时以读写方式打开腌制文件?
- javascript - D3在文本中动态加粗单词
- r - 未使用的参数
- python - 在 jupyter 中解压缩 .gz 扩展文件
- date - Xamarin - 图像保存到画廊没有日期
- excel - 如何减去一张纸中的范围并将值放入另一张纸中?