Способ найти, вернет ли функция обещание
Ниже у меня есть функция, которая возвращает обещание, которое разрешает true
. Есть ли способ узнать, возвратит ли функция обещание?
var myPromiseFunction = function(){
return Promise.resolve(true)
}
myPromiseFunction().then(function(value){
console.log(value) // => true
})
function mySyncFunction(){
return "hello"
}
willReturnPromise(myPromiseFunction) // => true
willReturnPromise(mySyncFunction) // => false
Ответы
Ответ 1
Есть ли способ узнать, вернет ли функция обещание?
Нет (не вызывает его вообще). Ваш лучший регресс здесь заключается в том, чтобы полагаться на согласованность в именовании и соглашениях API.
Просто для быстрого "доказательства" неспособности проверить тип возвращаемого значения, рассмотрите следующую функцию:
function maybeAPromise() {
if (Math.random() < .5) {
return Promise.resolve('foo');
} else {
return 'bar';
}
}
Хотя я лично считаю, что преимущества производительности динамических языков, таких как JavaScript, стоят их компромиссов, нет никаких сомнений в том, что отсутствие безопасности типа компиляции является одним из компромиссов в категории "отрицательных".
При этом Promise.resolve()
удобно, если вы просто хотите заставить результат быть Promise
. Например,
Promise.resolve(maybeAPromise()).then(...);
Ответ 2
Нет хорошего способа сделать это, но вы можете вызвать методы и проверить их возвращаемые значения.
function willReturnPromise(fn) {
const result = fn();
return result && typeof result.then === 'function';
}
Спецификация A + Promise не требует promises иметь что-либо, кроме функции с именем then
, поэтому это лучшее, что вы можете сделать, если хотите, чтобы функция работала со всеми реализациями Promise.
Вызов функции и отбрасывание результата просто для определения этого не является хорошей идеей.
Ответ 3
Проверьте возвращаемое значение после его вызова. В конце концов, это JavaScript, а не какой-то статически типизированный язык. У вас есть все те же опции:
function foo(func) {
var result = func();
if (result instanceof Promise) {
result.then(bar).catch(failure);
} else {
bar(result);
}
}
foo(myPromiseFunction);
foo(mySyncFunction);
Но я рекомендую против таких оптимизаций, так как это увеличивает сложность. Лучше позволить Promise.resolve()
сделать свое дело и свернуть ваш синхронный поток кода в ваш асинхронный. .then
делает это автоматически для вас на все, что вы возвращаете, поэтому я считаю этот подход вполне читаемым.