3

我正在为 Javascript 开发人员查看 A First Reason React 应用程序中的 Reason 示例

我看到他Js.Promise.resolve在使用时正在打电话bs-fetch

RepoData.fetchRepos()
  |> Js.Promise.then_(repoData => {
       handleReposLoaded(repoData);
       Js.Promise.resolve();
     })
  |> ignore;

我也在 BuckleScript 代码中看到了类似的代码。例如在Bucklescript Cookbook中:

Js.Promise.(
  Fetch.fetch "https://api.github.com/users/reasonml-community/repos"
  |> then_ Fetch.Response.text
  |> then_ (fun text -> 
      text 
      |> names
      |> Array.iter Js.log 
      |> resolve)
  |> ignore

在 JS 中,我们通常resolve在创建新的 Promise 时调用,而不是在使用返回 Promise 的函数时调用。那么为什么我们需要resolve在上述情况下调用呢?

4

1 回答 1

6

Js.Promise.then_要求返回一个新的承诺。

原因是 es6 的 promise 没有正确输入。回调中返回的值then是动态包装或(无限)展平的,因此它总是返回一个承诺,而不是一个嵌套的承诺。这意味着如果我们允许返回任何值(let then_: ((_ => 'a), Js.Promise.t(_)) => Js.Promise.t('a)),并且如果该值是一个承诺('a= Js.Promise.t('b)),它将具有返回类型Js.Promise.t(Js.Promise.t('b)),但返回的值实际上将被扁平化为一个Js.Promise.t('b)

then_接受回调中的一个承诺通过使您返回一个嵌套的承诺更加明显来缓解这一点。然而,仍然有可能resolve兑现承诺,所以这种类型仍然不健全,但它让你更难射中自己的脚。

在(可能不久的)将来会有一个健全而优雅的 Promise API,但由于设计和实现它是一项不平凡的任务,因此需要一些时间才能让它正确。

于 2017-11-23T09:21:38.650 回答