延迟技术是否仍然使用,虽然隐藏在公共API中?

时间:2016-07-05 09:38:47

标签: promise ecmascript-6

ES2015 Promise API中没有公开延迟 - 延迟概念是否仍在内部使用?

换句话说:延迟技术是否仍在使用,但最佳实践现在规定延迟不会暴露给用户态代码?

可以说Promise是与已解析值对应的公共API(状态为pendingsettled?),在某种意义上,包含对应于操作的内部延迟(使用状态{{ 1}},resolved?)。

1 个答案:

答案 0 :(得分:1)

延迟的概念未在规范中使用。 The word "deferred"在规范文本中恰好出现0次。

因此,不使用“延迟技术”。引擎和库通常只是将解析和拒绝直接放在promise对象本身上然后传递它。由于ECMAScript直接实现不能公开比请求更多的属性 - 引擎使用私有属性 - 在V8中这些是私有符号。

您可以在引擎中看到延迟使用的单词 - 但与您习惯的意义不同 - 在this example from v8中使用以下内容:

 var deferred = NewPromiseCapability(constructor);

但延迟对象实际上是一个承诺功能对象,你不能deferred.resolve而是使用你要做的内部API:

 switch (status) {
    case kPending:
      PromiseAttachCallbacks(this, deferred, onResolve, onReject);
      break;
    case kFulfilled:
      PromiseEnqueue(GET_PRIVATE(this, promiseResultSymbol),
                     onResolve, deferred, kFulfilled);
      break;
    case kRejected:
      if (!HAS_DEFINED_PRIVATE(this, promiseHasHandlerSymbol)) {
        // Promise has already been rejected, but had no handler.
        // Revoke previously triggered reject event.
        %PromiseRevokeReject(this);
      }
      PromiseEnqueue(GET_PRIVATE(this, promiseResultSymbol),
                     onReject, deferred, kRejected);
      break;
  }

也就是说,通过包装同步包装的promise构造函数,仍然可以很容易地创建deferred:

function Defer() {
    this.promise = new Promise((res, rej) => {
        this.resolve = res;
        this.reject = rej;
    });
}

var d = new Defer();
d.resolve(); // and so on

promise构造函数必须分配一个闭包,因此速度较慢 - 因此引擎通常在实现then之类的东西时不会直接调用它。