Я пытаюсь разобраться с отложенными / обещанными jQuery (используя v1.8 +).

После прочтения документации метод $.Deferred.then(...) принимает doneFilter и failFilter в качестве аргументов для выполнения и возвращает обещание, которое мы можем использовать для цепочки следующим образом:

function doDefer() {
    var $defer = $.Deferred();

    doSomethingAsynchronous(
        function () {
            $defer.resolve();
        },
        function () {
            $defer.reject();
        }
    );

    return $defer.promise();
}

doDefer()
    .then(function () {
        return;
    }, function () {
        // second `then` not called
    })
    .then(function (b) {
        // `b` is undefined, since first `then` returned without a value.
    }, function () {
        // fail end
    });

Два вопроса:

  1. Почему цепочка выполнения останавливается в doDefer(), если она попадает в первую функцию fail? Как я понимаю, then возвращает $.Deferred.promise(), как вторая цепочка then соединяется (и выполняется). then doneFilter / function / callback в первой цепочке всегда возвращается (?) - так почему / как jQuery обрабатывает failFilter по-другому?
  2. Почему then возвращает $.Deferred.promise(), а done / always / fail и т. Д. Возвращает $.Deferred? Какая польза от этого (и почему она отличается от then)?
0
keldar 17 Дек 2015 в 13:07

3 ответа

Лучший ответ

Почему цепочка выполнения останавливается в doDefer(), если она попадает в первую функцию fail? Как я понимаю, then возвращает обещание, как вторая цепочка then соединяется (и выполняется). then callback в первой цепочке всегда возвращается (?) - так почему / как jQuery по-разному обрабатывает failFilter?

Я не уверен, что понимаю вас правильно, но есть две вещи, которые вы должны знать:

Почему then возвращает $.Deferred.promise()

Потому что это обещание, которое разрешится с результатом соответствующего обратного вызова. Это не отложено, что вы можете решить сами. См. Также В чем разница между отложенным, обещанием и будущим в JavaScript?

… Пока done / always / fail и т. Д. Вернуть $.Deferred?

Они не Они просто возвращают объект, к которому они были призваны, независимо от того, было ли это обещанием или отсрочкой.

0
Community 23 Май 2017 в 12:31

Вы можете увидеть этот пример, его работа правильно:

function doDefer() {
    var $defer = $.Deferred();

    setTimeout( function(){
                doSomethingAsynchronous(
                    function ( value ) {
                        // func1 - value is a random number
                        $defer.resolve( value );
                    },
                    function () {
                        $defer.reject();
                    }
                );
            }, 1000 );

    return $defer.promise();
}

function doSomethingAsynchronous( func1, func2 ){
    // random number 0-10
    var random = Math.round( Math.random()*10 )
    if( random > 5 ){
        return func1.call( this, random );
    }else{
        return func2.call( this );
    }
}

doDefer().then(function ( value ) {
    // success
    // make double of random
    return value*2;
}, function () {
    // fail when random number < 5
})
.then(function (b) {
    // `b` is double of random number
    console.log(b);
}, function () {
    // fail end
});

Я надеюсь это поможет тебе

0
Khurram 17 Дек 2015 в 10:50

failHandler остановит выполнение, как вы сказали. Ключ должен смотреть на цепь. Обработчик сбоя будет выполнен, только если обещание, к которому он был прикован, отклонено. Убедитесь, что вы смотрите на каждое звено в цепочке как отдельное обещание.

Цепочка может быть переписана следующим образом.

dfd1 = doDefer();

dfd2 = dfd1.then( success1, fail1 );

dfd3 = dfd2.then( success2, fail2 );

В этом примере success1 будет вызываться только в случае разрешения dfd1. Если он отклонен, вместо него будет вызван fail1, и цепь остановится.

Аналогично, success2 будет вызываться только в том случае, если разрешен dfd2 (другими словами, success1 возвращает значение или разрешает возвращенное обещание). Единственный способ выполнения fail2 - если dfd2 явно отклонен success1 (всплывающее сообщение об ошибке не работает в реализации jQuery).

Tl; dr - сбои не объединяются и, как сказал @Bergi, обработка ошибок в jQuery нарушена

0
thedarklord47 18 Дек 2015 в 21:52