根据this question,当我们设置window.location时,javascript将“停止”执行或变成竞争条件。
有时我们需要在WebView中多次触发window.location = SOMESCH://xxx
以将“通知”发送回我们的应用程序。例如,设置window.location = myapp://loginButtonEnabled?e=1
告诉应用程序用户填写了一些nessasary信息并可以开始登录。似乎不可能做这样的事情:
function(){
window.location = myapp://loginButtonEnable?e=1;
window.location = myapp://hideHintView;
.....
window.location = myapp://theLastThing;
}
只会触发最后一个window.location = myapp://theLastThing
,然后Javascript的执行将停止(尽管我们通过在webView:shouldStartLoadWithRequest:navigationType:
中返回NO来停止在我们的应用中重定向。)
我觉得有趣的是,PhoneGap通过使用调度队列使这成为可能,但我仍然不知道它为什么有效,任何人都知道这个技巧?
顺便说一下,设置位置后有没有简单的方法来“恢复”执行?它比使用操作队列要好得多。答案 0 :(得分:5)
您需要为事件循环提供每次响应位置更改的机会。这样做的典型方法是使用具有小/零延迟的setTimeout
,这具有将执行移动到下一个事件循环滴答的效果。尝试这样的事情:
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而不是更改当前页面的位置 - 例如,请参阅 Triggering shouldStartLoadWithRequest with multiple window.location.href calls