如何检查 JavaScript 函数是否返回一个 Promise?

22

假设我有两个函数:

function f1() {
    return new Promise<any>((resolve, reject) => {
        resolve(true);
    });
}

function f2() {
}

我该如何知道f1是否会返回Promisef2不会呢?


6
首先,您需要解决停机问题,以查看它是否返回。或者您可以直接调用它并查看发生了什么。 - Derek 朕會功夫
我的意思是,如果我能有一个函数来检查f1是否是返回Promise的函数。 isPromiseFunction(f1); //true isPromiseFunction(f2); //false - tranminhtam
即使它返回一个 Promise,也不能保证下一次会这样做。function f3(){return Math.random() > 0.5 ? Promise.resolve(true): 'naaah'} - Yury Tarabanko
只是检查任何函数是否返回Promise,而不想调用它。 - tranminhtam
在场景中,我想检查一个函数是否返回Promise,以便正确处理该函数。该函数是两种类型中的一种。let isPromise = possiblePromise instanceof Promise ? possiblePromise : Promise.resolve(possiblePromise),参见http://stackoverflow.com/a/28123576/@tranminhtam - guest271314
显示剩余7条评论
4个回答

38

调用该函数,使用instanceof

let possiblePromise = f1();
let isPromise = possiblePromise instanceof Promise;

@AlonEitan 然后,在这里,会尝试使用 RegExp - guest271314
1
@AlonEitan 如果 f1 没有返回一个 Promise,函数的结果仍然可以传递给 Promise.resolve() - guest271314
相信我,我完全理解你的回答,但我完全不理解OP(我没有投反对票,实际上我投了赞成票 - 但我确实投了反对票并标记为“不清楚你在问什么”)。 - Alon Eitan
通过这种方式,您可以检查它是否是使用特定的Promise实现创建的Promise,即使它返回了有效的Promise,如果它是用另一个实现创建的,则会返回false。此外,我认为OP想知道函数是否返回Promise而不执行它(这是不可能的)。 - Antonio Val

15

所以这只是关于规范化输出的问题。然后通过Promise.resolve()等方法运行它。

var possiblePromise = f1();
var certainPromise = Promise.resolve(possiblePromise).then(...);
或者
var possiblePromises = [f1(), f2()];
Promise.all(possiblePromises).then(values => ...);

但您需要基本了解这些函数返回的内容。例如:两个示例都将失败

function f3(){
    return [somePromise, someOtherPromise];
}

var arrayOfPromisesOrValues = f3();

//here you'll still deal with an Array of Promises in then();
Promise.resolve(arrayOfPromisesOrValues).then(console.log); 
//neither does this one recognize the nested Promises
Promise.all([ f1(), f2(), f3() ]).then(console.log);

//only these will do:
Promise.all(f3()).then(console.log);
Promise.all([ f1(), f2(), Promise.all(f3()) ]).then(console.log);

您需要知道f3返回一个Promise数组或值并进行处理。就像您需要知道f1f2返回一个值或值的Promise。

总之,您需要基本了解函数返回什么才能通过适当的函数运行结果来解决Promise。


1

这是不可能完成的。

然而,你可以将任何函数转换为返回Promise的函数。在这里,这是我会做的事情。

const toPromise = function (f) {
  return function () {
    return new Promise((resolve, reject) => {
      const result = f.apply(null, Array.from(arguments));
      try {
        return result.then(resolve, reject); // promise.
      } catch (e) {
        if (e instanceof TypeError) {
          resolve(result); // resolve naked value.
        } else {
          reject(e); // pass unhandled exception to caller.
        }
      }
    });
  };
};

const f = (x) => x;
const g = (x) => Promise.resolve(x);
const h = (x) => Promise.reject(x);

// Naked value.
toPromise(f)(1).then((x) => {console.log(x)});
// Resolved Promise.
toPromise(g)(2).then((x) => {console.log(x)});
// Rejected Promise.
toPromise(h)(3).catch((x) => {console.log(x)});


无法完成。可以使用RegExp将函数解析为字符串。 - guest271314
1
不,那仍然不起作用。考虑一下来自 OP 评论的示例:function f3(){return Math.random() > 0.5 ? Promise.resolve(true): 'naaah'} - Kenan Banks
4
没有任何正则表达式可以猜测随机函数的返回值,但可以尝试编写一些代码来模拟和测试它。 - Kenan Banks
@guest271314,您如何确定从 const c = (value) => value < pivot? a(value): b(value)c是否返回一个Promise。特别是如果ab是封闭变量,因此完全超出了您的控制范围。 - Thomas
7
我想编写一个能够预测未来的正则表达式一定非常费力。 - Kenan Banks
显示剩余14条评论

1
对于NodeJS,我们可以使用内置模块util/types中的isPromise函数。文档链接在这里

import { isPromise } from "util/types";

// assume the JS object you want to test is "obj"
isPromise(obj);


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接