在我的代码中,我尝试在继续执行其余代码之前尝试延迟一段时间。很基本的。我使用自定义睡眠功能,因为javascript的原生睡眠功能根本不起作用。我实际上是在谷歌电子表格中的应用程序脚本中工作,所以也许这就是原因。但是以下代码位于电子表格应用程序脚本中html文件的<script>
标记中。
无论如何,当我使用sleep()
时,它正在setTimeout
function get_ids(db){
window.alert("before window.ids is saved?");
google.script.run.withSuccessHandler(getIdsFromAppscript).getIdsFromModel(db);
//this returns a result to getIdsFromAppscript but the following code doesn't wait
//for the result to be returned so I want to use sleep before the ids
//variable is returned by get_ids
setTimeout(function(){
window.alert("checking if ids is saved after 10s?");
window.alert("In timeout ids="+window.ids);
var ids= window.ids; //is non empty
},10000);
sleep(10000);
var ids= window.ids;
window.alert("after wait");
window.alert("after sleep ids="+ids); //is empty but should be non empty
return ids; //=window.ids , Need to return a non-empty result
}
function getIdsFromAppscript(result){
window.ids=result;
}
和睡眠功能:
function sleep(ms) {
var start = new Date().getTime(), expire = start + ms;
while (new Date().getTime() < expire) { }
return;
}
当前输出顺序基于window.alert()
:
1) before window is saved?
2) after sleep
3) after sleep ids= //basically empty which shouldn't be the case
4) checking if ids is saved after 10s?
5) In timeout ids= [.....] //non empty list
但是,所需的输出顺序是:
1) before window is saved?
2) checking if ids is saved after 10s?
3) In timeout ids= [.....] //non empty list
4) after sleep
5) after sleep ids= [...] //should be a non empty list
我写setTimeout的原因是为了表明10秒后,结果存储在window.ids
中,但即使在我睡了10秒甚至30秒后,我也可以#39;从window.ids获取结果。
我到底错在了什么?提前谢谢〜
答案 0 :(得分:3)
Java Script,尤其是通过V8引擎无法入睡。睡眠导致JavaScript运行的整个线程停止,这打破了异步的整个点。 setTimeout()
只等待你投入的时间内运行你推入的功能。它并没有停止其余的执行,无论先发生什么事都会先发生。
如果对您来说重要的是,按顺序发生某些事情,那么您需要使用回调或承诺。
代码中的一个例子可能是:
function doTimeout(ms) {
setTimeout(function(){
window.alert("checking if ids is saved after 10s?");
window.alert("In timeout ids="+window.ids);
var ids= window.ids; //is non empty
},ms);
}
function sleep(ms, callback) {
var start = new Date().getTime(), expire = start + ms;
while (new Date().getTime() < expire) { }
callback(ms);
}
sleep(10000, doTimeout);
答案 1 :(得分:1)
Javascript是单线程的。您必须从代码返回其他线程中的脚本才能执行。其他线程中的脚本包括处理超时事件的函数,保留或失败时调用的函数,以及使用XMLHttpRequest对象为异步请求提供的回调函数。
编写一个函数并将其调用sleep()
不会改变这一点。您可以将它waitingForGodot()
称为它所能产生的所有差异。你提供的代码所做的是在被调用的线程中花费大量的时间循环。它不会放弃控制并阻止所有其他脚本执行。如果它持续的时间足够长,我的浏览器会问我是否要中止(如你的)脚本。
答案 2 :(得分:0)
我在下面列出了两个示例,显示您的睡眠功能会阻止整个Javascript引擎。当我使用sleep
函数时,即使我设置了100 ms的间隔并且输出延迟了10秒,也不会执行间隔功能。但是,在第二个示例中,输出会立即以正确的间隔打印。这表明您的sleep
函数正在阻止整个执行引擎,这解释了您的ids
数组为空的原因。
function sleep(ms) {
var start = new Date().getTime(),
expire = start + ms;
while (new Date().getTime() < expire) {}
return;
}
function get_ids() {
document.write("before window.ids is saved?" + "<br>");
var counter = 0;
setInterval(function() {
while (counter < 100) {
document.write("checking if ids is saved after 10s?" + "<br>");
counter = counter + 1
}
}, 100);
sleep(10000);
documen.write("after wait");
}
document.write("Start");
get_ids()
document.write("End");
在这个例子中,我已经注释了你的睡眠功能,正如预期的那样,输出每100毫秒打印一次:
function sleep(ms) {
var start = new Date().getTime(),
expire = start + ms;
while (new Date().getTime() < expire) {}
return;
}
function get_ids() {
document.write("before window.ids is saved?" + "<br>");
var counter = 0;
setInterval(function() {
while (counter < 100) {
document.write("checking if ids is saved after 10s?" + "<br>");
counter = counter + 1
}
}, 100);
//sleep(10000);
documen.write("after wait");
}
document.write("Start");
get_ids()
document.write("End");