2

根据this question,当我们设置window.location时,javascript将“停止”执行或变成竞争条件。

有时我们需要window.location = SOMESCH://xxx在 WebView 内多次触发以将“通知”发送回我们的应用程序。例如设置window.location = myapp://loginButtonEnabled?e=1告诉应用程序用户已经填写了一些必要的信息并且可以开始登录。做这样的事情似乎是不可能的:

function(){
window.location = myapp://loginButtonEnable?e=1;
window.location = myapp://hideHintView;
.....
window.location = myapp://theLastThing;
}

只有最后一个window.location = myapp://theLastThing会被触发,然后 Javascript 的执行将停止(尽管我们通过在应用程序中返回 NO 停止了重定向webView:shouldStartLoadWithRequest:navigationType:)。

我发现有趣的是,PhoneGap 通过使用调度队列使这成为可能,但我仍然没有弄清楚它为什么起作用,有人知道诀窍吗?

顺便说一句,有没有一种简单的方法可以在设置位置后“恢复”执行?这将比使用操作队列好得多。

4

1 回答 1

5

您需要让事件循环每次都有机会响应位置更改。执行此操作的典型方法是使用setTimeout具有小/零延迟的 a,这具有将执行移至下一个事件循环滴答的效果。尝试这样的事情:

var q=[];

function dequeue() {
  window.location='myapp://'+q.shift();
  if (q.length>0) setTimeout(dequeue,0);
}

function notifyApp(cmd) {
  q.push(cmd);
  if (q.length==1) setTimeout(dequeue,0);
}

notifyApp('loginButtonEnable?e=1');
notifyApp('hideHintView');
notifyApp('theLastThing');

至于 javascript 执行停止,设置window.location不应该有这种效果,除非它实际上导致页面更改 - 也许尝试使用上面的技术,看看你的 javascript 在最后一次notifyApp()调用后是否继续。

编辑:解决此问题的另一种方法是创建临时 iframe,而不是更改当前页面的位置 - 例如,请参阅 使用多个 window.location.href 调用触发 shouldStartLoadWithRequest

于 2012-10-08T17:09:22.773 回答