【问题标题】:When should I call Promise.resolve() directly?我什么时候应该直接调用 Promise.resolve() ?
【发布时间】:2015-09-08 15:02:18
【问题描述】:

我已经看到可以直接调用本机 ES6 Promise.resolve() - 作为静态方法。 Facebook 在他们的 Flux 示例中就是这样使用它的。

但在什么情况下我应该这样做?排队?还是不使用window.setTimeout()

【问题讨论】:

    标签: ecmascript-6 es6-promise


    【解决方案1】:

    当您需要创建已解决的承诺时,您应该调用Promise.resolve(object)。例如,您可能有一个函数开始从服务器下载资源或返回其缓存版本:

    function getImage(imageUrl) {
        if (imageUrl in this.cache) {
            // no need to download, return immediately
            return Promise.resolve(this.cache[imageUrl]);
        } else {
            return new Promise(function(resolve, reject) {
                // start downloading and eventually resolve
            });
        }
    }
    

    【讨论】:

    • 只能在上面调用then()
    • 是的,如果调用代码期望返回承诺,这是必需的。因此,您不会破坏调用约定,请在此处查看更多示例 - devdocs.io/javascript/global_objects/promise/resolve
    • 使用“已经解决”具有误导性。返回的 Promise 不必已经被解析,并且对返回的 Promise 的 then() 调用的回调不一定会“很快”(下一个周期..)被调用,并且可能需要无限量的时间取决于在 resolve 电话中发布的内容。
    • 我同意@Amit,我认为“在它可能已经解决的情况下创建一个promise”更合适。很好的例子,它说明了一个实际的用例。
    • @Bergi - 我主要是说我们正在讨论海洋有多潮湿 - 这对现实世界没有影响:-)
    【解决方案2】:

    Promise.resolve(42) 只是一个简写形式

    new Promise(function(resolve) {
        resolve(42);
    });
    

    因此,每当您发现自己在做这样的事情时,即从现有值创建承诺时,您都可以改用 Promise.resolve

    【讨论】:

      【解决方案3】:

      从语义上讲,返回 Promise 的函数是异步函数,并且如您所知,可以链接在一起:

      a().then(b).then(c).catch(failure);
      

      虽然同步函数也可以是异步链的一部分,但这只是因为.then 函数会自动将您传递给它的函数的返回值提升为 Promise。例如。如果b 和/或c 返回的值不是承诺,那么链仍然有效,但如果a 返回一个非承诺值,那就是TypeError

      在大多数情况下你可能知道a返回什么,所以这很好,但如果你不知道a 会返回什么(比如你正在做泛型编程),那么你可以这样做:

      Promise.resolve(a()).then(b).then(c).catch(failure);
      

      abc 现在在这方面被同等对待:

      • 如果a 返回1,那么b 将很快被1 调用。
      • 如果a 返回一个承诺,那么b 将被链接在a 后面。

      Promise.reject 方法对故障链完成同样的事情。

      此外,在您只需要立即解决的承诺的情况下,这些方法会很方便。例如

      [a, b, c].reduce((p, f) => p.then(f), Promise.resolve()).catch(failure);
      

      【讨论】:

      • 当他们中的一个投掷时,他们不会受到平等对待。您可以考虑改用Promise.resolve().then(a)…
      • @Bergi 好点,谢谢。这两种方式略有不同,因此请务必选择适合您的方式。如果a 确实是新序列中的第一个方法并且它有一个同步组件,那么可能需要确保它的同步部分在一个返回之前已经运行(大多数浏览器 API 至少努力同步进行输入验证通过检查承诺状态和原因使它们在 js 调试器中可观察),或者只是为了避免额外的调度。但如果abc 是真的等于,那么您的建议可能更可取。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-12-11
      • 2010-09-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多