【问题标题】:jQuery: How to return when data conditionally is requested via AJAX?jQuery:当通过 AJAX 有条件地请求数据时如何返回?
【发布时间】:2012-02-17 02:53:35
【问题描述】:

我有一个函数调用另一个函数来获取数据。该数据可能在本地缓存,或者我可能不得不去获取它。本地缓存很容易。但是,如果我通过 $.getJSON 获取它,而不通过关闭异步来锁定浏览器,是否有某种方法仍然可以将该数据恢复到原始功能?

即在以下代码中:

1) 既然 parseData() 返回时 bar() 不再存在,那么 dataX 去哪儿了?

2) 如果没有 bar() 和 parseData() 都会调用的另一个回调层,并且在请求进行时没有锁定浏览器,我如何将 dataX 从 parseData() 恢复到 foo()?

var foo = function () {

    $('body').text(bar());

};

var bar = function () {

    var parseData = function (dataX) {
        // do something to data
        return dataX;
    };

    if (localStorage.hasOwnProperty('someKey')) {
        return localStorage.getItem('someKey');
    else {
        $.getJSON('http://somewhere.api.com?fubar=good', parseData);
    }

};

【问题讨论】:

    标签: jquery ajax asynchronous getjson


    【解决方案1】:

    bar 函数没有返回,因此直接在 text() jQuery 函数中调用它不会设置任何文本(因为返回不是文本)。

    您可以更改代码流以传入要更改其文本的元素,并让parseData 函数实际调用该元素的.text() 函数:

    var foo = function () {
    
        //here we call the `bar` function and pass the element we want to change the text of as an argument
        bar('body');
    
    };
    
    var bar = function (element_str) {
    
        //here we use the argument we passed to create a jQuery object of the element to use later
        var $element = $(element_str);
    
        var parseData = function (dataX) {
    
            //instead of trying to return the value from the server, we just set the text of the element passed in
            $element.text(dataX);
        };
    
        if (localStorage.hasOwnProperty('someKey')) {
    
            //here we manually call the `parseData` function to add the locally stored string to the DOM
            parseData(localStorage.getItem('someKey'));
        else {
    
            //here we pass the `parseData` function as the callback function for this AJAX call so it can set the text in the DOM when the AJAX function has come back successfully
            $.getJSON('http://somewhere.api.com?fubar=good', parseData);
        }
    
    };
    

    【讨论】:

    • bar() 确实有条件返回:return localStorage.getItem('someKey'); .text() 只是一个简单的示例;我需要将 dataX 返回到 foo() 以便 foo() 用它做其他事情,所以我不能只传递元素。 (foo() 在私有模块构造函数中;这样做,每个 foo() 都必须重新实现 bar() 否则会执行的函数)。
    • @BrianFreud - 是的,但是 $.getJSON 的完整方法(parseData)在请求完成之前不会运行,这是在函数已经返回 undefined 之后.text() 方法。
    • 是的,所以问题是,我怎样才能让 bar() 持续存在,或者至少让 foo() 等待,直到 getJSON 请求完成?或者是将 getJSON 请求设置为同步的唯一可能方法?
    • 如果它不同步,它永远不会在它被调用的函数返回之前完成。而且,一开始就让它同步并不是一个好主意。
    【解决方案2】:

    进行异步调用时无法返回。而只是调用 foo 作为回调:

    var foo = function (text) {
    
        $('body').text(text);
    
    };
    
    var bar = function () {
    
        var parseData = function (dataX) {
            // do something to data
            foo(dataX.someText);
        };
    
        if (localStorage.hasOwnProperty('someKey')) {
            foo(localStorage.getItem('someKey'));
        else {
            $.getJSON('http://somewhere.api.com?fubar=good', parseData);
        }
    
    };
    

    【讨论】:

    • 可以 $.getJSON 将参数传递给 parseData,在 jQuery 默认参数之外吗?即,传递对(在这种情况下)
    • 我不确定我理解你的意思。 parseData 可以访问其闭包范围内的所有内容。
    • 啊,好的,那就行了。我将重载 foo() 然后能够同时成为被调用者和调用者。
    【解决方案3】:

    由于请求是异步的,因此这是不可能的,除非您请求的服务器支持 CORS,在这种情况下,您可以使请求同步。由于可能会导致糟糕的浏览器体验,我不建议这样做。

    我建议允许bar 接受一个回调,您可以使用该回调在完成时执行操作。

    编辑:

    试试这个:

    var foo = function () {
    
        $('body').text(bar());
    
    };
    
    var bar = function () {
    
        var parseData = function (dataX) {
            // do something to data
            localStorage.setItem('someKey',dataX);
            foo();
        };
    
        if (localStorage.hasOwnProperty('someKey')) {
            return localStorage.getItem('someKey');
        else {
            $.getJSON('http://somewhere.api.com?fubar=good', parseData);
            return "loading...";
        }
    
    };
    

    当浏览器不支持 localStorage 时会发生什么?还是您只是不针对那些浏览器。

    【讨论】:

    • 我曾想过,但无法让它发挥作用。 foo() 是全局函数,而 bar() 是构造函数内部的私有函数。构造函数设置一个事件,当事件触发时,调用 foo() 作为事件的回调。 foo() 通过事件传递了对 bar() 的引用。 (所以构造函数调用一个外部函数,并传递一个引用,这样外部函数就可以调用构造函数内部的私有函数。)
    • 从 parseData() 中调用 bar() 似乎没有工作,因为 afaik,现在无法访问 bar() - parseData() 可以返回到 bar(),但尝试调用bar() 提出了未找到的预期功能。
    • 是的,我不是针对那些。这是仅针对 HTML5/localStorage 兼容版本的 Chrome、FF 和 Opera 的大型 GM 脚本的一小部分。
    猜你喜欢
    • 1970-01-01
    • 2016-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多