我正在尝试将一系列同步调用变成异步,我正在使用...完成...我对这个东西很新,但是从我在这个主题上所做的所有阅读最近两天,我的代码应该可行。嗯,它确实有效,但并不完全符合我的意思。
在下面的测试代码中,我进行了五次调用,每次调用都需要不同的时间(在我的示例中,它基于字符串的长度...每个字符1/2秒)。我的期望是花费较少时间的调用(即我的示例中的较短长度字符串)将首先完成我快速启动所有五个调用,并且期望结果按照执行时间较短的顺序显示为更长的执行时间。
这是我的代码:
var cars = ["Saab", "Chrysler", "Volvo", "BMW", "GT"];
loopAll(cars);
document.getElementById("demo").innerHTML += "Start!<br>";
function loopAll(array) {
for (var i in array) {
$.when( encapsulate(array[i]) ).done( printIt );
}
function encapsulate(name){
var a = $.Deferred();
setTimeout(function(){pause(name.length*500);a.resolve(name);}, 0);
return a;
}
}
function printIt(name){
document.getElementById("demo").innerHTML += name + "<br>";
}
function pause(ms) {
ms += new Date().getTime();
while (new Date() < ms){}
}
阵列中的每个元素都被打印出来,我可以看到它们一个接一个地弹出。但是,它们似乎是同步的,因为它们以数组的原始顺序显示,并且在每个显示的元素之间发生暂停。但是,我的期望是较短的执行功能比较长的执行功能更快完成(和显示)。
注意:我不是要对数组进行排序。我的目的是触发多个调用,让较短的执行完成,而不是顺序完成。我只使用字符串数组作为例子。
答案 0 :(得分:1)
在这种情况下,超时块并没有真正做任何事情。它会立即执行其功能块。
JavaScript是单线程的,通过使用自制的&#39;暂停&#39;你有效地阻塞线程并导致每个循环同步执行的方法。
如果您有一些同步代码,并且异步备选方案不可用,您可以使用Web worker将它们从主线程中移除。
答案 1 :(得分:0)
在我下面的测试代码中,我进行了五次调用,每次调用都需要一次 不同的时间(在我的例子中,它是基于长度的 字符串...每个字符1/2秒。)
setTimeout(function(){pause(name.length*500);a.resolve(name);}, 0);
对于创建的每个duration
对象,0
似乎设置为$.Deferred()
?不确定pause
的预期结果?
我的期望是花费更少时间的电话(即电话号码 我的例子中的长度较短的字符串)将首先完成 快速拨打所有五个电话,并期望显示结果 按照执行时间越短,执行时间越长。
尝试将duration
的{{1}}设置为setTimeout
name.length*500
&#13;
var cars = ["Saab", "Chrysler", "Volvo", "BMW", "GT"];
loopAll(cars);
document.getElementById("demo").innerHTML += "Start!<br>";
function loopAll(array) {
for (var i in array) {
$.when( encapsulate(array[i]) ).done( printIt );
}
function encapsulate(name){
var a = $.Deferred();
setTimeout(function(){a.resolve(name);}, name.length*500);
return a;
}
}
function printIt(name){
document.getElementById("demo").innerHTML += name + "<br>";
}
// function pause(ms) {
// ms += new Date().getTime();
// while (new Date() < ms){}
// }
&#13;
答案 2 :(得分:0)
你列出的代码有点像红鲱鱼;事实证明,问题在于声明&#34;我试图将一系列同步调用变为异步。&#34;在大多数JavaScript环境中,这根本不可能。
JS环境通常是单线程的,因此即使您将来使用setTimeout
来安排代码执行一段时间,该代码仍将 阻止该线程。有关示例,请参阅this JSFiddle:http://jsfiddle.net/BinaryMuse/r4ct92c5/
除非您在节点中使用Web Workers(在浏览器中)或external processes,fibers或native addons之类的内容,否则您无法异步执行JS代码