代码之家  ›  专栏  ›  技术社区  ›  Marcus Junius Brutus

`在承诺的执行者中解析和拒绝函数

  •  3
  • Marcus Junius Brutus  · 技术社区  · 7 年前

    假设客户机程序员同时定义和使用 resolve 传递给 Promise 我天真地以为我完全控制了 决定 函数,因此我可以定义它接受多个参数。

    但是下面的代码( jsFiddle )失败:

    <html>
      <script>
       const promise = new Promise(function executor(resolve, reject) {
         setTimeout(function () {
           resolve(42, true);
           }, 1000);
       });
       promise.then(function resolveCallback(answer, howCertain) {
         console.log('callback called with arguments: ('+answer+', '+howCertain+')');
         console.log('the answer is: '+answer+'. I am '+(howCertain?'very':'not very')+' certain about that');
       });
      </script>
    </html>
    

    上面的代码实际上打印在控制台上:

    callback called with arguments: (42, undefined)
    the answer is: 42. I am not very certain about that
    

    再深入一点,我写了下面的代码( jsFiddle ):

    <html>
      <script>
       const promise = new Promise(function executor(resolve, reject) {
         console.log('entering executor, resolve is: ['+resolve+']'.);
         setTimeout(function () {
           console.log('about to call resolve');
           resolve(42);
           console.log('returning from resolve');       
           }, 1000);
       });
       console.log('about to call "then"');
       promise.then(function resolveCallback(answer) {
         console.log('the answer is: '+answer);
       });
      </script>
    </html>
    

    它实际上在控制台上打印以下内容:

    entering executor, resolve is: [function t() { [native code] }]
    about to call "then"
    about to call resolve
    returning from resolve
    the answer is: 42
    

    这说明了许多有趣的事情:

    • 在客户端程序员有机会调用之前调用执行器 then 履行承诺。然而, 决定 中的参数 executor 函数不是 undefined .
    • 这个 resolveCallback 在对的调用中作为参数传递的函数 然后 决定 函数传递给 执行人 . 此外,它不会与 决定 从内部呼叫 执行人 功能。

    JavaScript实现这一点的唯一方法(我可以想到)是,实现实际上正在插入某种“代理”。 决定 reject 异步链接到实际 决定 拒绝 由客户端程序员提供的功能。这也解释了为什么您不能为 决定 拒绝 功能:因为水管不工作。

    这个心理模型是正确的还是我遗漏了什么?

    1 回复  |  直到 7 年前
        1
  •  4
  •   Bergi    7 年前

    客户机程序员定义传递给承诺执行者的解析函数

    不,他没有(正如你的实验证实的那样)。执行者在 new Promise 创造。

    当我打电话的时候 then 就承诺而言,我不会通过 resolve 我选择的功能?

    不,你通过了 on Resolve 侦听器回调,或 actually an onFulfill 回拨。

    我的新思维模式正确吗?

    是的,地下有更多的水管。

    事实上, 新承诺 构造函数只提供代理解析程序函数。

    承诺包含状态机。它是一个表示(one!)异步结果。因此,你可以打电话 .then() 在同一个Promise对象上多次调用,回调总是会传递结果。

    它不是包装 executor 函数,它不会像您所调用的那样频繁地调用执行器 然后 . 遗嘱执行人只被传唤一次,给 生产者 访问解析器函数(状态机的输入)。这个 消费者 那个电话 然后 观察状态机的输出,与这个完全分离——正如您所说,它们是 异步 已链接。

    也可以看看 this . 对于你的精神模型, this 是一个易于理解的实现 Promise 类(SAN保证异步和错误处理)。