您将该函数描述为“my_async_function”,但您使用它的方式是synchronous而不是asynchronous。
您的示例代码需要阻塞——如果“my_async_function”是真正异步的(非阻塞),那么self.write(result)
在您调用“my_async_function”之后,以下代码行将立即执行。如果函数需要任何时间(我的意思是any)返回一个值,self.write(result)
最终会写什么?也就是说,如果self.write(result)
执行之前result
曾经有一个值,你不会得到预期的结果。因此,“my_async_function”必须阻塞,它必须等待返回值才能继续前进,因此它不是异步的。
具体到您的问题$.sweetget('/remote/url/', {})
:为了实现这一点,您必须能够阻止,直到 ajax 请求(它本质上是异步的——它将第一个 A 放入 AJAX)返回一些东西。
您可以通过延迟返回sweetget
直到 XHR 状态发生变化来破解同步调用,但是您将使用while
循环(或类似的东西)并冒着阻塞浏览器 UI 线程或设置其中一个“此脚本也正在占用”的风险长”警告。Javascript 不提供线程控制。你不能指定你当前的线程正在等待,所以继续做一分钟别的事情。您也可以通过手动测试超时阈值来解决这个问题。
现在人们应该开始怀疑:为什么不直接使用回调呢?无论您如何切片,Javascript 都是单线程的。不sleep
,不thread.sleep
。这意味着任何同步代码都会阻塞 UI。
在这里,我已经模拟了sweetget
大致的样子。如您所见,一旦执行进入该紧密while
循环,您的浏览器线程就会锁定。实际上,在我的计算机上,在浏览器显示无响应的脚本对话框之前,ajax 请求甚至不会触发。
// warning: this code WILL lock your browser!
var sweetget = function (url, time_out) {
var completed = false;
var result = null;
var run_time = false;
if (time_out)
run_time = new Date().getTime();
$.ajax({
url: url,
success: function(data) {
result = data;
completed = true;
},
error: function () {
completed = true;
}
}); // <---- that AJAX request was non-blocking
while (!completed) { // <------ but this while loop will block
if (time_out) {
if (time_out>= run_time)
break;
run_time = new Date().getTime();
}
}
return result;
};
var t = sweetget('/echo/json/');
console.log('here is t: ', t);
试试看:http: //jsfiddle.net/AjRy6/