jquery延迟回退 - 可能的范围问题

时间:2014-08-01 12:04:15

标签: javascript jquery jquery-deferred

我正在尝试收听一系列延期请求以完成。我想添加回退,以便如果初始url失败,那么它将加载一个json文件。 (我已经在这里加载了jsbin页面以阻止任何跨域问题。)

我原来的代码就像是

function makeCalls() {

        var deferreds = [];

        var statsDeferred = 
            $.get("http://thiswillfail.yesitwill");

        statsDeferred.fail(function() {
          $.get("http://run.jsbin.com/")
                    .done(function() {
                         statsDeferred.resolve();
                    });

        deferreds.push(statsDeferred);

        return deferreds;
    }


var deferreds = makeCalls();

$.when.apply(null, deferreds).done(function() {
            alert("done");
        });

然而,它在statsDeferred.resolve();

行失败了

http://jsbin.com/pofejotu/1/

我尝试添加$ .proxy调用来维护范围,但它不起作用。

function makeCalls() {

        var deferreds = [];

        var statsDeferred = 
            $.get("http://thiswillfail.yesitwill");

        statsDeferred.fail($.proxy(function() {
          $.get("http://run.jsbin.com/")
                    .done($.proxy(function() {
                         statsDeferred.resolve();
                    }, this));
            }, this));

        deferreds.push(statsDeferred);

        return deferreds;
    }


var deferreds = makeCalls();

$.when.apply(null, deferreds).done(function() {
            alert("done");
        });

http://jsbin.com/vonibuhe/1/edit

两者都失败了

statsDeferred.resolve();
  

未捕获的TypeError:undefined不是函数

1 个答案:

答案 0 :(得分:2)

如果您想链接承诺,正确使用的方法是.then()

function makeCalls () {
    var statsDeferred = $.get("http://thiswillfail.yesitwill");

    statsDeferred = statsDeferred.then(
        null, /* on success, keep the initial promise's state */
        function(){ return $.get("http://run.jsbin.com/"); }
    );

    return statsDeferred;
}

statsDeferred.resolve();
Uncaught TypeError: undefined is not a function

您遇到的错误是DeferredPromise之间的差异。

  • a Deferred公开了改变其内部状态的方法(.resolve.reject),
  • Promise只允许您查询此状态,并对其做出反应(.done.fail,...)

API函数通常会返回Promise,因此外部用户无法插入预期的状态。例如,“修复”代码的一种方法如下:

function makeCalls() {
    // make a deferred, you will be the one in control of its state :
    var deferred = $.Deferred();

    var firstGet = $.get("http://thiswillfail.yesitwill");
    firstGet.done(function(response) { deferred.resolve(response); })

    // if the first request fails, run the second :
    firstGet.fail(function(){
        var secondGet = $.get("http://run.jsbin.com/");
        secondGet.done(function(response) { deferred.resolve(response) };
        secondGet.fail(function() { deferred.reject() });
    });

    // only return the Promise to the outer world :
    return deferred.promise();
}