我正试图将承诺的resolve
函数的工作与ECMAScript规范中的相应过程相匹配。更具体地说,我正在寻找在使用对象值调用resolve函数时的规范。
举几个例子:
new Promise((resolve) => {
resolve("hello");
});
new Promise((resolve) => {
resolve({a: 100});
});
这两个承诺之间有一个区别:传递给resolve
函数的值的类型。
设F为活动函数对象。
Assert:F有一个[[Promise]]内部槽位,其值是Object。
让承诺。[[承诺]].
让alreadyResolved是。[[alreadyResolved]] .
如果<<li>em> alreadyResolved 。[[取值]]istrue,返回undefined.
<设置em>alreadyResolved 。[[取值]]totrue.设置em>
如果SameValue(分辨率,)承诺是对,那么
。让selfResolutionError为新创建的TypeError对象。
b。Return RejectPromise(promise,selfResolutionError).
如果Type(resolution)不是Object,则
。Return FulfillPromise(promise,resolution)。
让是Get(分辨率,"then") .
如果then是突然结束,则
。返回RejectPromise (,。[[价值]])。
让thenAction是。[[价值]].
如果IsCallable(thenAction)是false,那么
。Return FulfillPromise(promise,resolution)。
让theenjobcallback为HostMakeJobCallback(thenAction)。
让job为NewPromiseResolveThenableJob(promise,resolution,theenjobcallback)。
执行HostEnqueuePromiseJob (工作。[[工作]],工作。[[Realm]])。
<返回strong>定义.返回strong>
我不能确定在哪里处理有一个对象作为参数而没有then
属性的情况。
步骤9获取then
属性
- 让是Get(分辨率,"then")。
主要有四种可能的结果:
then
不是对象的属性,因此然后(变量)表示具有[[Value]]undefined
的完成记录。then
是对象的一个属性,但是计算它会产生一个异常(例如,它是一个getter,而getter会遇到一个异常)。那么就是所谓的突然完成。then
是对象的属性,但不是函数then
是对象的属性,它是一个函数。
步骤10检查这些结果之一:
- 如果then是一个突然完成,那么
a. Return RejectPromise(promise,then.[[Value]]).
下面是使10.a
发生的代码片段:
let obj = {
get then() {
throw "sorry";
}
};
new Promise(resolve => resolve(obj))
.catch((err) => console.log("rejected with ", err))
这表示then
不一定打算作为函数计算(它是一个getter,所以代码必须执行才能确定),但是访问它使得无法知道它是否会是一个函数,因为它会产生一个异常。规范中提到了[[Get]]
中getter的执行步骤11是对检索到的完成记录的[[Value]]
字段的简单赋值(注意还有其他字段,如[[Type]]
)
- 让thenAction是。[[价值]]。
步骤12检查该值是否为函数。
- 如果IsCallable(thenAction)是false,则
a.返回FulfillPromise(promise,resolution)。
如果不是函数,则以该对象作为值来完成主承诺。
其余步骤处理然后是函数的情况。