在ReasonML中从Js.Promise转换为"理性承诺"



我遇到过这样一种情况,即库使用理性承诺作为默认的一个分支,而不是另一个分支。我发现很难从一个分支切换到另一个分支,因为我一辈子都不知道如何使用理性承诺。我在Js方面也好不到哪里去。承诺,但那不是重点。

有问题的图书馆是理性的apollo客户。该分支还有一系列其他改进,包括reason-promise作为默认的promise实现。那个分支就是下一个分支。

举个例子,在原因承诺问题中,我有一个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);

当我在创建apollo/clientauthlink时尝试将其与reason-promise一起使用时,我会得到以下错误:

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.tPromise.t之间的错误处理原理不同。后者使用Belt.Result模块处理错误(如上所示https://github.com/aantron/promise#handling-带结果的错误(,而前者使用拒绝(这通常用catch(在JavaScript中(或catch_(在Reason中(来处理(。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-拒绝了解更多细节。

注意,看起来apollo已经开始使用香草承诺(https://github.com/reasonml-community/reason-apollo-client/pull/57)。

相关内容

  • 没有找到相关文章

最新更新