Как отказаться (и правильно использовать) Обещания?
Короткий рассказ:
Говоря оОбещания / А +, как правильно отказаться от обещания - выдать ошибку? Но если я скучаю поcatch
- все мое приложение взорвется!
Как пользоватьсяpromisify
и каковы его преимущества (может быть, вам нужно прочитать более длинную версию)?
Является.then(success, fail)
действительноанти-модель и я должен всегда использовать.then(success).catch(error)
?
Более длинная версия, описывается как реальная проблема жизни (хотелось бы кого-нибудь прочитать):
У меня есть библиотека, которая используетпевчая птица (Библиотека реализации A + Promise), для извлечения данных из базы данных (речь идет оSequelize). Каждый запрос возвращает результат, но иногда он пуст (пытался что-то выбрать, но его не было). Обещание входит вresult
функция, потому что нет причины для ошибки (отсутствие результатов не является ошибкой). Пример:
Entity.find(1).then(function(result) {
// always ending here, despite result is {}
}).catch(function(error) {
// never ends here
});
Я хочу обернуть это и проверить, является ли результат пустым (не могу проверить это везде в моем коде). Я сделал это:
function findFirst() {
return Entity.find(1).then(function(result) {
if (result) { // add proper checks if needed
return result; // will invoke the success function
} else {
// I WANT TO INVOKE THE ERROR, HOW?! :)
}
}).catch(function(error) {
// never ends here
});
}
findFirst().then(function(result) {
// I HAVE a result
}).catch(function(error) {
// ERROR function - there's either sql error OR there is no result!
});
Если вы все еще со мной - надеюсь, вы поймете, что случилось. Я хочу как-то запустить функцию ошибки (где "ERROR function"). Дело в том, что я не знаю как. Я пробовал эти вещи:
this.reject('reason'); // doesn't work, this is not a promise, Sequelize related
return new Error('reason'); // calls success function, with error argument
return false; // calls success function with false argument
throw new Error('reason'); // works, but if .catch is missing => BLOW!
Как вы можете видеть по моим комментариям (и по спецификации), выдача ошибки работает хорошо. Но есть большаяно - если я скучаю по.catch
Скажите, все мое приложение взрывается.
Почему я не хочу этого? Допустим, я хочу увеличить счетчик в моей базе данных. Мне плевать на результат - я просто делаю HTTP-запрос .. Так что я могу позвонитьincrementInDB()
, который имеет возможность возвращать результаты (даже по причинам теста), поэтому естьthrow new Error
если это не удалось. Но так как меня не волнует ответ,иногда я не буду добавлять .catch заявление, право? Но теперь - если я не (намеренно или по ошибке) - я закончу с вашим приложением узла.
Я не нахожу это очень хорошим, Есть лилучше способ решить это, или я просто должен иметь дело с этим?
Мой друг помог мне, и я использовал новое обещание, чтобы исправить ситуацию, например:
function findFirst() {
var deferred = new Promise.pending(); // doesnt' matter if it's Bluebird or Q, just defer
Entity.find(1).then(function(result) {
if (result) { // add proper checks if needed
deferred.resolve(result);
} else {
deferred.reject('no result');
}
}).catch(function(error) {
deferred.reject('mysql error');
);
return deferred.promise; // return a promise, no matter of framework
}
Работает как шарм!Но Я попал в это:Обещание Anti Patterns - статья вики, написанная Петкой Антоновой, создателем Bluebird (реализация A +). Явно сказано, что этонеправильно.
Итак, мой второй вопрос - это так? Если да - почему? И как лучше?
Большое спасибо за чтение этого, я надеюсь, что кто-то потратит время, чтобы ответить на это для меня :) Я должен добавить, что я не хотел слишком сильно зависеть от фреймворков, поэтомуSequelize
а такжеBluebird
это просто вещи, с которыми я в конечном итоге работал. Моя проблема с Обещаниями как глобальными, а не с этими конкретными рамками.