1. ホーム
  2. javascript

[解決済み] 約束を守らなかったり、拒否したりするとどうなる?

2023-05-31 05:34:50

質問

私は、プロミスを返すシナリオを持っています。 プロミスは基本的にajaxリクエストによって引き起こされます。

プロミスを拒否すると、サーバーエラーが発生したというエラーダイアログが表示されます。

私がやりたいことは、応答コードが401のとき、約束を解決することも拒否することもしたくありません(すでにエラーダイアログが表示されているからです)。私は単にログインページにリダイレクトしたいのです。

私のコードは次のようなものです。

function makeRequest(ur, params) {
  return new Promise(function (resolve, reject) {
    fetch(url, params).then((response) => {
      let status = response.status;    
      if (status >= 200 && status < 300) {
        response.json().then((data) => {
          resolve(data);
        });
      } else {
        if (status === 401) {
          redirectToLoginPage();
        } else {
          response.json().then((error) => {
            if (!error.message) {
              error.message = constants.SERVER_ERROR;
            }
            reject({ status, error });
          });
        }
      }
    });
  });
}

ご覧の通り、ステータスが401の場合、ログインページにリダイレクトしています。約束は解決も拒否もされていません。

このコードに問題はないでしょうか、それともこれを達成するためにもっと良い方法があるでしょうか。

どのように解決するのですか?

プロミスはJavascriptのプロパティを持つ単なるオブジェクトです。 魔法はありません。 そのため、プロミスの解決や拒否に失敗しても、状態を"pending"から他のものに変更することはできません。 プロミスは通常のJavascriptのオブジェクトなので、これはJavascriptの基本的な問題を引き起こしません。 どのコードもプロミスへの参照を保持しない場合、プロミスはまだ(たとえまだ保留中であっても)ガベージコレクションされます。

ここでの本当の結果は、その状態が決して変更されない場合、プロミスの消費者に何を意味するのか、ということです。 どんな .then() または .catch() リスナーは決して呼び出されることはありません。 プロミスを使うほとんどのコードは、将来のある時点で解決または拒否されることを期待しています(それがそもそもプロミスが使われる理由です)。 もしそうでなければ、そのコードは一般的に決してその仕事を終えることができません。

そのタスクのための仕事を終わらせる他のコードがあって、プロミスはその仕事をすることなくただ放棄される可能性があります。 しかし、それはプロミスがどのように動作するように設計されたかではなく、一般的にプロミスの消費者がどのように動作することを期待しているかということではありません。

ステータスが401の場合、ログインページにリダイレクトされるのがお分かりになると思います。 プロミスは解決も拒否もされていません。

このコードで大丈夫でしょうか?または、これを達成するために何か良い方法がありますか。

この特定のケースでは、すべてOKで、リダイレクトはやや特殊でユニークなケースです。 新しいブラウザ ページへのリダイレクトは、現在のページの状態 (すべての Javascript の状態を含む) を完全にクリアするので、リダイレクトでショートカットを行い、他のものを未解決のままにするだけでもまったく問題ありません。 新しいページがロードされ始めると、システムは Javascript の状態を完全に再初期化するので、まだ保留されていた約束はすべてクリーンアップされます。