【问题标题】:Triggering a Javascript callback after a completed ajax call within an object在对象内完成 ajax 调用后触发 Javascript 回调
【发布时间】:2012-07-29 00:54:09
【问题描述】:

我试图在通过 AJAX 调用创建 Javascript 对象后触发操作。我的对象看起来像这样:

function API(uid,accessToken){      
        $.ajax("path/to/file", {
            type: "POST",
            data: { user: uid, auth: accessToken },
            dataType: "json",
            success: function(jsonData) {
                arrayname = jsonData[values]
            }
        });
}

我尝试在对象设置完成后使用 JQuery 的 $.when 函数进行回调(即数组填充了 ajax 响应),如下所示:

        $.when( API = new API(uid, accessToken) ).then(function() {
                ...success function...
        });

...但是$.when 函数触发时数组名值仍未定义。从函数的角度来看,即使对象值尚未设置,延迟对象也会被解析。从那以后,我尝试了多种方法来根据整个 ajax 调用的完成和变量的设置来延迟 API 对象,但我有点坚持最好的方法。

任何指针将不胜感激!谢谢。

【问题讨论】:

  • 谢谢,已修复该错误(与手头的问题无关)。

标签: javascript jquery jquery-deferred


【解决方案1】:

您可以在创建对象时传递回调函数,如下所示:

function API(uid,accessToken, callback){      
        $.ajax("path/to/file", {
            type: "POST",
            data: { user: uid, auth: accessToken },
            dataType: "json",
            success: function(jsonData) {
                arrayname = jsonData[values]
                callback(jsonData[values])
            }
        });
}

然后像这样实例化对象

var api = new API(uid, accessToken, function(array) {
    // success function
});

【讨论】:

  • 谢谢,是的,我以前也这样做过,当然可以。但是,我从 UI 中抽象出这些数据对象,并且需要能够在整个应用程序中使用它们——换句话说,同一对象/方法的回调函数可能因环境而异。这就是为什么我希望尽可能使用 JQuery 的 $.when 函数。
  • 嗯,那我就糊涂了。如果 ajax 调用在它所在的位置,它不会在初始化时只运行一次吗?
  • 这个会,但是这个对象上的其他方法(每个方法都可能进行 ajax 调用)可以在整个应用程序中任意运行。我想将数据对象与使用它的视图分开。例如,一种方法允许我获取与特定对象关联的标签,并且它们可能在不同时间以不同方式显示。因此,目标是在组装对象的函数之外建立回调。
【解决方案2】:

如果问题是由于在“then”回调之后运行的“success”回调,您也可以尝试将成功回调转换为 then 回调。我不使用 JQuery,但我猜它看起来像:

function API(uid,accessToken){      
    return $.ajax("path/to/file", {
        type: "POST",
        data: { user: uid, auth: accessToken },
        dataType: "json",
    }).then(function(jsondata){
        arrayname = jsondata[values]
    });
}

$.when( API = new API(uid, accessToken) ).then(function() {
    // ...
});

【讨论】:

    【解决方案3】:

    您使用$.when 的原因是当您关联多个promise、异步任务等的回调时。从jQuery 1.5 开始,所有对$.ajax 的调用和所有包装器($.get$.post)全部返回promises。因此,除非您想做$.when(ajaxCall1, ajaxCall2),否则您不需要使用$.when 语句来包装此调用。

    既然你想过滤来自服务器的结果,你应该使用promise的pipe方法:

    function API(uid, accessToken)
      return $.post(
        type: 'POST'
        ,data: { user: uid, auth: accessToken }
        ,dataType: 'json'
      )
        .pipe(function(json) {
          return json[values];
        })
      ;
    }
    

    这使您可以按照自己的方式编写代码:

    API(uid, token)
      .then(
        // success state (same as promise.done)
        function(arrayname /* named from your sample script*/) {
          alert('success! ' + arrayname);
        }
        // error state (same as promise.fail)
        ,function(jqXHR, status, error) {
          console.warn('oh noes!', error);
        }
      )
      .done(function() { /* done #2 */ })
      .fail(function() { /* fail #2 */ })
    ;
    

    注意:promise.pipe() 还允许您过滤(更改传递给的数据)错误回调。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多