[英]Converting from Js.Promise to `reason-promise` in ReasonML
我有一種情況,圖書館使用reason-promise作為默認的一個分支而不是另一個分支。 我發現很難從一個分支切換到另一個分支,因為在我的一生中,我無法弄清楚如何使用理性承諾。 我在 Js.Promise 方面並沒有好多少,但這不是重點。
有問題的圖書館是reason-apollo-client 。 該分支還有許多其他改進,包括作為默認promise
實現的reason-promise
。 該分支是下一個分支。
舉例來說,在reason-promise-question找到,我有一個Js.Promise
function 獲取當前令牌值。 它有以下類型:
unit => Js.Promise.t(
Js.Nullable.t(string)
)
function 可以在代幣中找到並在下面復制。 這是一個虛擬的 function,沒有綁定。 關鍵是看如何讓它編譯。
[@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,
),
);
},
_,
)
});
我們如何將其轉換為理由承諾? 請隨心所欲地成為雙語者。
先感謝您。
您應該能夠將 vanilla 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_
(在 Reason 中))。 Promise.Js.t
的中間產品封裝了與 JavaScript promise 相同的理念。
為了將中間產品轉換為最終的Promise.t
,因此您需要明確指出當/如果中間產品 promise 被拒絕時應該發生什么。 這可以通過幾種不同的方式來完成,但作為示例,您可以這樣做:
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 。
注意,它看起來像阿波羅已經轉向使用香草承諾( https://github.com/reasonml-community/reason-apollo-client/pull/57 )。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.