我遇到过这样一种情况,即库使用理性承诺作为默认的一个分支,而不是另一个分支。我发现很难从一个分支切换到另一个分支,因为我一辈子都不知道如何使用理性承诺。我在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/client
authlink
时尝试将其与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.t
和Promise.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)。