查找函数是不是会返回承诺的方法

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 等动态语言的生产力优势值得他们权衡取舍,但不可否认的是,缺乏编译时类型安全性是“负面”类别中的权衡之一。

话虽如此,如果您只想将结果强制为PromisePromise.resolve() 很方便。例如,

Promise.resolve(maybeAPromise()).then(...);

【讨论】:

resolvemethod 的问题是我不能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 时,未定义不是函数

如何按顺序执行承诺并返回所有结果[重复]

返回 jQuery 承诺的 Vuex 动作不起作用,.fail 不是函数

从 .map() 方法中的调度函数返回承诺