2015-04-16 2 views
5

Для углового проекта мне нужно выполнить обещания, и я сталкиваюсь с ситуациями, когда я не уверен, что делаю. Вот один мой код:Угловые условные обещания

return Action1().then(function (data) { 
    var defer = $q.defer(); 
    if (data.condition) { 
     $q.all([Action2(), Action3(), Action4()]).then(function() { 
      defer.resolve(); 
     }); 
    } else { 
     defer.reject("error_code"); 
    } 
    return defer.promise; 
}); 

Action1, Мотор2, действий3 и действий4 работают обещания функции. Много обещаний и действий зависит от условий. Могу ли я это сделать и быть уверенным, что моя основная функция будет всегда решена или отвергнута?

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

return Action1().then(function (data) { 
    var defer = $q.defer(); 
    if (data.condition) { 
     defer.resolve($q.all([Action2(), Action3(), Action4()]); 
    } else { 
     defer.reject("error_code"); 
    } 
    return defer.promise; 
}); 

ответ

3

Нет, это не так. Ваша первая функция останется навсегда, если один из Action2(), Action3() или Action4() сделал «бросок» и отклонил обещание $q.all(…) - ваш отложенный никогда не разрешается. Это наиболее распространенная ошибка deferred antipattern, которую вы использовали здесь.

Ваша вторая функция смягчает это, но все еще слишком сложна. Вам вообще не нужно откладывать! Просто вернуть обещание прямо, и использовать $q.reject:

return Action1().then(function (data) { 
    if (data.condition) { 
     return $q.all([Action2(), Action3(), Action4()]); 
    } else { 
     return $q.reject("error_code"); 
    } 
}); 

Или, как это происходит внутри then обработчика, вы можете также использовать throw "error_code".

+0

Вы редактировали свой ответ. Я просил вторую часть, но вы отвечаете на нее во время публикации. Я начинаю с обещаний. Я изучаю форму (откладываю с решимостью и отвергаю), и я использовал ее во всем проекте. Большое спасибо за указание на то, что я могу использовать непосредственно $ q или ошибку throw. – JeromeModi

1

Спасибо за ваш ответ, я вижу свою ошибку в первой версии кода. Я думаю, что это q.all, что возмущает меня.

Я прочитал отложенный антипаттерн. Он сказал, что нам не нужно создавать отложенные объекты без всякой причины.

Простой случай это:

return Action1().then(function() { 
    return $q.all([Action2(),Action3(), Action4()]);   
}); 

Но из-за, если (data.condition) Я не могу это сделать. Является ли мой второй код единственным способом сделать это? Я в каком-то случае, или я должен использовать отсрочку?

Это говорит о «обещании», но с Угловым Я не знаю, хорошо ли это (libs кажутся неподдерживаемыми).

Cheers,

+0

Да, вы должны использовать отсрочки только для промитификации. Хотя в угловом, два наиболее используемых асинхронных метода '$ http' и' $ timeout' уже возвращают обещания, поэтому вам редко это нужно. – Bergi

+0

В Angular 1.3 я увидел, что они ввели новый синтаксис для конструктора $ q. Что вы думаете об этом? Полезно ли это использовать? – JeromeModi

+1

Право, конструктор обещаний. Да, это хорошая практика, чтобы использовать его вместо отложенных, это новый стандарт для обещаний. Но «отсроченный антипаттерн» по-прежнему остается одним и тем же, может быть, «антипаттером» обещания. Не используйте, если функция, с которой вы работаете, уже возвращает обещания. – Bergi

Смежные вопросы