繁体   English   中英

JQuery / Javascript内联回调

[英]JQuery / Javascript inline callback

在龙卷风我们有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
}

1.8之前的jQuery版本支持通过async: false设置同步ajax调用 它是一个有限制的黑客(没有跨域或jsonp,锁定浏览器),如果可能的话我会避免它。

有几个可用的库为Javascript中的异步操作提供了一些语法糖。 例如:

...但是我认为没有任何东西可以提供您正在寻找的同步语法 - 由于JavaScript在浏览器中的工作方式,因此总会涉及回调。

您将该函数描述为“my_async_function”,但您使用它的方式是同步而不是异步

您的示例代码需要阻止 - 如果“my_async_function”是真正的异步(非阻塞),则在您调用“my_async_function”之后,将立即执行以下代码行self.write(result) 如果函数需要任何时间(我的意思是任何时间 )来返回一个值,那么self.write(result)最终会写什么? 也就是说,如果在result有值之前执行self.write(result) ,则不会得到预期的结果。 因此,“my_async_function”必须阻塞,它必须在前进之前等待返回值,因此它不是异步的。

具体到你的问题, $.sweetget('/remote/url/', {}) :为了实现这一点,你必须能够阻止,直到ajax请求(这本质上是异步的 - 它放入AJAX中的第一个A回来了。

您可以通过延迟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/

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM