bugfix> javascript > 投稿

私はサービスワーカーが初めてです。私は次のトレーニングを行っていますモバイルWebスペシャリスト Udacityから提供され、そのためにgoogle-chromeを使用しています。 ネットワークからの応答を取得したいのですが、ステータスとして404を返す場合は、ネットワークからの別の応答も取得します。 これは、ネットワークから一度だけフェッチするコードです。このコードは完全に機能します:

self.addEventListener('fetch', function(event) {
  event.respondWith(
    fetch(event.request).then(function(response) {
      if (response.status === 404) {
        return new Response("Whoops, not found");
      }
      return response;
    }).catch(function() {
      return new Response("Uh oh, that totally failed!");
    })
  );
});

response.status === 404 を取得した後にエラーをスローして、このコードを更新しました try/catch でも同じように管理します 。更新されたコードは次のとおりです。

self.addEventListener('fetch', function(event) {
 try {
  event.respondWith(
    fetch(event.request).then(function(response) {
      if (response.status === 404) {
        throw (Error);
      }
      return response;
    }).catch(function() {
      return new Response("Uh oh, that totally failed!");
    })
  );
 } catch (Error) {
   event.respondWith(
    fetch('/imgs/dr-evil.gif').then(function(response) {
      if (response.status === 404) {
        return new Response('couldn\'t fetch twice');
      }
      return response;
    }).catch(function() {
      return new Response("Uh oh, that totally failed twice!");
    })
  );
 }
});

サービスワーカーを使用してネストされたフェッチを行うより良い方法があることは知っていますが、ここで間違ったことを知りたいです。

回答 1 件
  • 私はこれを実行していないので、いくつかの調整が必要になる可能性がありますが、このようなことを試してください。現在のコードの問題は、最初のフェッチプロミスチェーンが常にResponseに解決されることです。最初の then のいずれか  または最初の catch で 、ここで "Uh oh, that totally failed!" の応答を返します 。ザ・ event.respondWith  その応答を受け取り、喜んでその方法に沿って進みます。

    外側の try/catch  同期空間に存在します。フェッチは非同期チェーンを開始するため、コードはフェッチの実行コンテキストにないため、外側のキャッチに到達する方法はありません。

    互換性がService Workerとasync/awaitの両方で同じである場合(わかりません)、コードを構造化するためのはるかに友好的な方法になるので、それを見てみるとよいでしょう。

    self.addEventListener('fetch', function(event) {
        event.respondWith(
            fetch(event.request).then(function(response) {
                if (response.status === 404) {
                    throw (Error);
                }
                return response;
            }).catch(function() {
                return fetch('/imgs/dr-evil.gif').then(function(response) {
                    if (response.status === 404) {
                        throw (Error);
                    }
                    return response;
                })
            }).catch(function() {
                return new Response("Uh oh, that totally failed twice!");
            })
        ); 
    });
    
    

あなたの答え