Обработка ветвей с промисами

У меня есть проблема с промисами jQuery 1.9.1, где мне потенциально нужна условная логика, которая вернет еще одно отложенное, и я не уверен, как с этим справиться. Это была моя лучшая попытка, но, как показывают комментарии ниже, когда я нажимаю ветку else, я все равно нажимаю вторую функцию .then(), где я надеюсь, что смогу вернуться к пользователю. Любые шаблоны того, как справиться с таким сценарием?

storage.provision(c)

.then(function(rc){
    if(rc === 0){
        storage.write(c);
    }else{
        return options.onSuccess(rc); //how i got back to the users callbacks/promise, but this
        //takes me to the .then below
    }
})
 //storage.write returns a promise as well, do I do another .then 
// like this?
.then(function(rc){
    //I was hoping this would catch, the storage.write() case, and it does, but it also catches
    //the retun options.onSuccess(rc) in the else case.
    options.onSuccess(rc);
})


.fail(function(e){
    //handle error using .reject()
});

person rooftop    schedule 20.03.2013    source источник
comment
Этот пост может вам помочь: stackoverflow.com/questions/12149993/   -  person mattytommo    schedule 21.03.2013
comment
Этот пост поможет вам лучше понимать обещания. В общем, если вы хотите использовать условные операторы, вы должны сохранить обещание как переменную и выполнить свои then success или fail внутри своих условных выражений, вы, похоже, делаете это наоборот.   -  person acconrad    schedule 21.03.2013


Ответы (1)


Это становится проще, если принять точку зрения, что options.onSuccess(rc); выполняется безоговорочно во втором .then(), но никогда в первом.

Таким образом, первый .then() должен передать rc либо:

  • если rc === 0, в ответ на storage.write(c) завершение
  • или сразу если rc !== 0.

.then() действительно удобен для этого, потому что он, естественно, позволяет вернуть значение нового промиса из обратного вызова done.

storage.provision(c).then(function(rc) {
    if(rc === 0) {
        var dfrd = $.Deferred();
        storage.write(c).done(function() {
            dfrd.resolve(rc);
        }).fail(dfrd.fail);
        return dfrd.promise();
    } else {
        return rc;//pass on rc to the second .then()
    }
}).then(function(rc){
    options.onSuccess(rc);
}).fail(function(e){
    //handle error using .reject()
});

Я уверен, что существуют и другие подходы, но это самое близкое, что я могу придумать к вашей первоначальной концепции.

Было бы неплохо не создавать новый Deferred, когда rc === 0, но это наиболее реалистичный подход к передаче rc, избегая необходимости изменять storage.write(), чтобы вести себя таким образом.

person Beetroot-Beetroot    schedule 21.03.2013