Упрощение обещаний в Javascript
-
21-12-2019 - |
Вопрос
Эквивалентны ли следующие фрагменты кода?
Версия 1
function doSomething() {
var defer = $q.defer();
foo().then(function() {
bar().then(function() {
defer.resolve();
});
});
return defer.promise;
}
Версия 2
function doSomething() {
return foo().then(bar);
}
Решение
Между этими двумя подходами есть много различий.
Основное различие между этими двумя фрагментами заключается в том, что в version 2
вы неявно передаете разрешенное значение из foo
прямо к bar
.В дополнение к этому doSomething
решу что угодно bar
решит, тогда как в version 1
результат отбрасывается.
Некоторые дополнительные важные замечания, сделанные Бенджамином Грюнбаумом:
(a) Если полоса является эталонной ошибкой 1 отклоняет внутреннее обещание и 2 броски.
(b) 1 требует ссылки на $ Q, где 2 является агностикой.
(с) версия 1 не является исключениями и отказ будет проглочен, где версия 2 позволит вам. Перевернуть отказ.;Есть несколько меньших различий.См. Stackoverflow.com/questions/22539815
Вы также можете написать это так.
Таким образом, вы не получите неявную передачу разрешенного значения из foo
к bar
(теперь это ясно), что может сбивать с толку или легко упускать из виду.Это также может быть полезно, если вы хотите что-то сделать с разрешенными значениями foo
или bar
прежде чем вернуть их.
function doSomething() {
return foo().then(function(res){
// maybe do something with the result of foo
return bar(res);
}).then(function(res){
// maybe do something with the result of bar
return res;
});
}
Создание отложенного объекта вручную должно быть сведено к минимуму и, как правило, является антипаттерном.
https://github.com/petkaantonov/bluebird/wiki/Promise-anti-patterns#the-deferred-anti-pattern
Ключевой принцип, демонстрируемый здесь, заключается в том, что обещание принимает состояние возвращенного обещания (или thenable ) внутри своего метода разрешения.