在龙卷风中我们有gen
模块,它允许我们编写这样的结构:
def my_async_function(callback):
return callback(1)
@gen.engine
def get(self):
result = yield gen.Task(my_async_function) #Calls async function and puts result into result variable
self.write(result) #Outputs result
我们在jquery
或其他javascript库中是否有相同的语法糖?
我想要这样的事情:
function get_remote_variable(name) {
val = $.sweetget('/remote/url/', {}); //sweetget automatically gets callback which passes data to val
return val
}
答案 0 :(得分:1)
1.8之前的jQuery版本支持sync ajax calls via the async: false
setting。它是一个有限制的黑客(没有跨域或jsonp,锁定浏览器),如果可能的话我会避免它。
有几个可用的库为Javascript中的异步操作提供了一些语法糖。例如:
...但是我认为没有任何东西可以提供您正在寻找的同步语法 - 由于JavaScript在浏览器中的工作方式,因此总会涉及回调。
答案 1 :(得分:1)
您将该功能描述为“my_async_function”,但您使用它的方式是 synchronous 而不是 asynchronous 。
您的示例代码需要阻止 - 如果“my_async_function”是真正的异步(非阻塞),则在您调用“my_async_function”后会立即执行以下代码行self.write(result)
。如果函数需要任何时间(我的意思是任何)来返回一个值,那么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);