簡體   English   中英

從 Js.Promise 轉換為 ReasonML 中的“reason-promise”

[英]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.tPromise.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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM