ES8 await与ES6 Promise.resolve()如何判定参数是否为thenable?
await与Promise.resolve()对Thenable对象的判定规则 针对ES6原生Promise和ES8await运算符,当参数已确定为非原生Promise时,两者判定是否为Thenable对象的逻辑完全一致,具体规则如下:
核心判定条件
需同时满足以下两点,才会被视为Thenable对象:
- 能成功读取对象的
then属性(读取过程不抛出任何错误); - 读取到的
then属性值,其typeof结果为function。
关键细节拆解
- 读取
then属性的容错:如果读取对象的then属性时抛出异常(比如then是一个会触发错误的getter),则直接将原对象作为Promise的兑现值,不判定为Thenable。 then属性的类型校验:只有then的值是函数时才符合要求,若为undefined、null、字符串、数字等非函数类型,均不视为Thenable。then方法调用的容错:判定为Thenable后,调用其then方法时若抛出错误,该错误会被捕获并作为Promise的拒绝原因,但这一步不影响“是否为Thenable”的判定结果。
示例验证
- 标准Thenable对象
const validThenable = { then(resolve) { setTimeout(() => resolve("completed"), 100); } }; await validThenable; // 最终得到"completed",判定为Thenable
then为非函数类型
const invalidThenable = { then: "not a function" }; await invalidThenable; // 直接返回该对象,不视为Thenable
- 读取
then时抛出错误
const errorOnGet = { get then() { throw new Error("Cannot access 'then' property"); } }; await errorOnGet; // 返回errorOnGet对象,不视为Thenable
then方法调用时抛出错误
const errorOnCall = { then() { throw new Error("Error occurred in then method"); } }; await errorOnCall; // 抛出错误(Promise被拒绝),但仍被判定为Thenable
内容的提问来源于stack exchange,提问作者Don Hatch
相关产品推荐
相关产品推荐

