【问题标题】:Promise resolve used as a function?Promise resolve 用作函数?
【发布时间】:2018-10-10 15:30:34
【问题描述】:

我最近一直在使用 Javascript 中的 Promises,但我很难理解这里到底发生了什么。

正在使用initMap 回调设置 Google 地图脚本 URL。所以当谷歌地图完成加载时,这个回调就会触发。

依次调用resolveFunc()resolvefunc() 在承诺中设置,但我没有得到这部分:

resolveFunc = resolve;

设置它等于resolve函数有什么用?

<script>
  var resolveFunc = null;
  var promise = new Promise(function(resolve, reject) {
    resolveFunc = resolve;
  });
  promise.then(function() {
    console.log('loaded');
  });
  function initMap() {
    resolveFunc();
  }
</script>

<script src="https://maps.googleapis.com/maps/api/js?callback=initMap" async defer></script>

【问题讨论】:

  • 或许更好理解:var promise = new Promise(resolve =&gt; { window.initMap = resolve; })
  • 你了解 JSONP 的工作原理吗?
  • 是的,在查看了这一切并在 cmets 的帮助下,我明白现在会发生什么。

标签: javascript google-maps ecmascript-6 promise


【解决方案1】:

我能看到这种构造的唯一原因是您希望能够访问在加载 google maps api 时解析的 Promise。

  1. 创建了一个新的 promise 对象。
  2. 该承诺的解析函数被分配到窗口变量resolveFunc 的范围之外
  3. .then 被分配给当 Promise 解决时发出控制台日志的 Promise。
  4. 当外部 gmaps 脚本运行 initMap 函数时,将调用分配的解析函数。
  5. .then 内的console.log 将触发。

我看不出有什么需要在 initMap 中运行代码而无需承诺构造也可以实现。

【讨论】:

    【解决方案2】:

    我以前从未见过这种结构。

    我只能想到一个原因:允许某种模块化。谷歌地图 URL 的加载将触发该承诺的解决。同时,其他模块可能已将.then 附加到此承诺,以便在加载此脚本时运行。

    那个全局的promise 变量真的很丑,但它可以用于这个目的。

    注意:我指的是一般意义上的“模块”:一些相当独立、有凝聚力的代码块。

    【讨论】:

    • 哦,现在我明白了,它已分配给 resolve 函数,但直到调用 resolveFunc() 才执行,因为这实际上是指 resolve 函数。
    • 对。 Bergi 的评论显示了实现相同目标的更好方法。但重点是这个承诺是从 JSONP 回调中解决的。如果我是对的,这样做的原因是将这个承诺暴露给额外的回调。
    【解决方案3】:

    这种模式背后的想法是加载的脚本:

    src="https://maps.googleapis.com/maps/api/js?callback=initMap"
    

    ...,应该能够解决承诺。为此,脚本需要调用 promise 构造函数提供的 resolve 函数。但是由于resolve 是该构造函数的本地变量,因此作者使用了一种解决方案,他们将该函数分配给一个全局 变量,该变量 可用于加载的脚本。

    该脚本肯定会查看 url 中的 callback 参数,并提取它后面的值。它将被分配给某个变量,比如callback,然后它们将触发解析:

    window[callback]();
    

    这将是 resolveFunc 的同义词,而后者又是 resolve 的同义词。

    该脚本无法通过调用 resolve 来做到这一点:

    resolve();
    

    ...因为那将是一个未知变量。

    【讨论】:

      【解决方案4】:

      这种方法被称为延迟模式,特别是 implemented in jQuery。它很可能是antipattern,但在这里可能是合理的,因为这是从 Google Maps API 回调转变为 Promise 的合理方式。

      promise 解析被推迟到resolveFunc 回调被调用。 promise 是全局的,可以在应用程序内部使用。如果不使用,由于上述原因,这可以被认为是反模式:

      当您不真正理解 Promise 并将它们视为美化的事件发射器或回调实用程序时,很容易陷入这种情况。

      可能只是:

      <script>
        function initMap() {
          console.log('loaded');
        }
      </script>
      

      【讨论】:

        猜你喜欢
        • 2019-12-14
        • 2021-11-05
        • 1970-01-01
        • 1970-01-01
        • 2019-01-20
        • 1970-01-01
        • 2022-06-11
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多