查找函数是不是会返回承诺的方法
Posted
技术标签:
【中文标题】查找函数是不是会返回承诺的方法【英文标题】:Way to find if function will return promise查找函数是否会返回承诺的方法 【发布时间】:2015-10-15 17:55:12 【问题描述】:下面我有一个函数,它返回解析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
【问题讨论】:
github.com/dfilatov/vow/blob/master/lib/vow.js#L892 【参考方案1】:有什么方法可以查出一个函数是否会返回一个承诺?
否(不是没有实际调用它)。您最好的办法是依赖命名和 API 约定的一致性。
只是为了快速“证明”无法测试返回类型,请考虑以下函数:
function maybeAPromise()
if (Math.random() < .5)
return Promise.resolve('foo');
else
return 'bar';
虽然我个人认为 javascript 等动态语言的生产力优势值得他们权衡取舍,但不可否认的是,缺乏编译时类型安全性是“负面”类别中的权衡之一。
话虽如此,如果您只想将结果强制为Promise
,Promise.resolve()
很方便。例如,
Promise.resolve(maybeAPromise()).then(...);
【讨论】:
resolve
或method
的问题是我不能unpromise a sync function。所以一旦它被转换,我就不能在同步庄园中使用它了。
我认为这是否是一个“问题”值得商榷,但你是对的,因为这是一个限制。 Promise
(本机或蓝鸟)API 并没有太大的限制。这是一个存在于 JavaScript 运行到完成语义的最深处的限制。
@ThomasReggi 这是经典的“你的函数是什么颜色?”问题:journal.stuffwithstuff.com/2015/02/01/…
@MattGreer 我完全忘记了那篇文章;是的,这是完全相同的问题。
在使用promise时,我一般使用Promise.resolve
来强制我所有的函数有相同的'color'【参考方案2】:
没有什么好的方法可以做到这一点,但是您可以调用这些方法并检查它们的返回值。
function willReturnPromise(fn)
const result = fn();
return result && typeof result.then === 'function';
A+ Promise 规范不要求 Promise 具有除名为 then
的函数之外的任何内容,因此如果您希望该函数与所有 Promise 实现一起使用,这是您可以做的最好的事情。
调用函数并丢弃结果只是为了确定这不是一个好主意。
【讨论】:
应该将fn
包裹在try / catch
否?
是的,但我真的认为你根本不应该这样做。只回答问题的字母然后提及这不是一个好主意。【参考方案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
会自动为您返回任何内容,因此我觉得这种方法非常易读。
【讨论】:
Promise.resolve(p) == p;
不起作用。而是使用instanceof Promise
。
@Bergi - 嗯,both work 在 Chrome、Firefox 和 Opera 中,但我的在 Safari 中不起作用,所以我会更新到你的。谢谢!以上是关于查找函数是不是会返回承诺的方法的主要内容,如果未能解决你的问题,请参考以下文章
在返回承诺的函数上使用 .success 时,未定义不是函数