我正在A First Reason React app for Javascript developers
看一个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中,我们通常在创建新的promise时调用resolve
,而不是在使用返回promise的函数时。那么为什么我们需要在上述情况下调用resolve
?
答案 0 :(得分:5)
Js.Promise.then_
要求返回新的承诺。
原因是es6承诺没有合理的输入。 then
回调中返回的值动态地被包装或(无限)展平,因此它总是返回一个promise,而不是一个嵌套的promise。这意味着如果我们允许返回任何值(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
承诺仍然是可能的,所以这种类型仍然不合理,但它会使你在脚下射击更加困难。
在(可能接近)未来将会有一个声音和优雅的承诺API,但由于设计和实现它是一项非常重要的任务,因此需要花费一些时间才能做到正确。