如何解决在ReasonML中从Js.Promise转换为`reason-promise`
我遇到的情况是,图书馆使用reason-promise作为默认的一个分支,而不是另一个。我发现很难从一个分支切换到另一个分支,因为在我的一生中,我无法弄清楚如何使用理性承诺。我对Js.Promise的了解不是很好,但这不重要。
有问题的图书馆为reason-apollo-client。该分支还有很多其他改进,包括reason-promise
作为默认的promise
实现。该分支是next branch。
通过示例,可以在reason-promise-question处找到一个Js.Promise
函数,该函数可以为我获取当前的令牌值。它具有以下类型:
unit => Js.Promise.t(
Js.Nullable.t(string)
)
该功能可以在Tokens中找到,并在下面复制。这是一个伪函数,没有绑定。关键是要了解如何进行编译。
[@bs.val] [@bs.scope "localStorage"]
external setItem: (string,string) => unit = "setItem";
let setUserToken: string => Js.Promise.t(unit) =
token => Js.Promise.resolve(setItem("auth",token));
[@bs.val] [@bs.scope "localStorage"]
external getItem: string => Js.Nullable.t(string) = "getItem";
let getUserToken: unit => Js.Promise.t(Js.Nullable.t(string)) =
() => Js.Promise.resolve(getItem("auth"));
let setTempuserToken: string => Js.Promise.t(unit) =
_ => Js.Promise.resolve();
let getTempuserToken: unit => Js.Promise.t(Js.Nullable.t(string)) =
() => Js.Promise.resolve(Js.Nullable.undefined);
当我在创建reason-promise
apollo/client
时尝试与authlink
配合使用时,出现以下错误:
unit => Js.Promise.t(
Js.Nullable.t(string)
)
Error: This expression has type
Js.Promise.t(Js.Json.t) = Js.Promise.t(Js.Json.t)
but an expression was expected of type
Promise.t(Js.Json.t) = Promise.rejectable(Js.Json.t,Promise.never)
这是authlink
函数:
let authLink =
ApolloClient.Link.ContextLink.makeAsync((~operation as _,~prevContext as ctx) => {
Tokens.getUserToken()
->Js.Promise.then_(
token => {
switch (token->Js.Nullable.toOption) {
| None =>
Tokens.getTempuserToken()
->Js.Promise.then_(
token => Js.Promise.resolve(Js.Nullable.toOption(token)),_,)
| Some(token) => Js.Promise.resolve(Some(token))
}
},)
->Js.Promise.then_(
fun
| None => Js.Promise.resolve(Js.Json.null)
| Some(token) => {
Js.Promise.resolve(
[%raw
{| (context,token) => ({
headers: {
...ctx.headers,authorization: `Bearer ${token}`
}
}) |}
](
ctx,token,),);
},)
});
我们如何将其转换为原因承诺?请随心所欲地欺骗自己。
谢谢你。
解决方法
您应该能够将原版 Js.Promise.t
转换为 Promise.t
。
首先,您必须将 Js.Promise.t
转换为 Promise.Js.t
。这可以通过
let myIntermediatePromise = myJsPromise |> Promise.Js.fromBsPromise
额外的 Promise.Js.t
类型存在的原因是 Js.Promise.t
和 Promise.t
之间的错误处理原理不同。后者使用 Belt.Result
模块处理错误(如 https://github.com/aantron/promise#handling-errors-with-result 所示),而前者使用拒绝(通常使用 catch
(在 JavaScript 中)或 catch_
(合理))。 Promise.Js.t
的中间产品封装了与 JavaScript 承诺相同的理念。
为了将中间产品转换为最终的 Promise.t
,您需要明确指出当/如果中间承诺被拒绝时会发生什么。这可以通过几种不同的方式来完成,但作为一个例子,你可以这样做:
let myFinalPromise = myIntermediatePromise |> Promise.Js.toResult
这会将您原来的 Js.Promise.t('a)
转换为 Promise.t(Result('a,Js.Promise.error))
。
如果您想进一步转换为 Promise.t('a)
,您必须明确处理可能出现的错误。
有关详细信息,请参阅 https://github.com/aantron/promise#advanced-rejection。
请注意,从那以后,阿波罗似乎已经开始使用普通 Promise (https://github.com/reasonml-community/reason-apollo-client/pull/57)。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。