0

나는이 오류가 계속 응답 :서비스 작업자 오류 : 이벤트가 이미

Uncaught (in promise) DOMException: Failed to execute 'respondWith' on 'FetchEvent': The event has already been responded to.

내가 비동기 물건은 가져 오기 함수 내에서 계속 경우 해당 서비스 노동자가 자동 ​​응답 알고,하지만 꽤 작동하지 수 비트는이 코드에서 위반자가됩니다.

importScripts('cache-polyfill.js'); 

self.addEventListener('fetch', function(event) { 

    var location = self.location; 

    console.log("loc", location) 

    self.clients.matchAll({includeUncontrolled: true}).then(clients => { 
    for (const client of clients) { 
     const clientUrl = new URL(client.url); 
     console.log("SO", clientUrl); 
     if(clientUrl.searchParams.get("url") != undefined && clientUrl.searchParams.get("url") != '') { 
     location = client.url; 
     } 
    } 

    console.log("loc2", location) 

    var url = new URL(location).searchParams.get('url').toString(); 

    console.log(event.request.hostname); 
    var toRequest = event.request.url; 
    console.log("Req:", toRequest); 

    var parser2 = new URL(location); 
    var parser3 = new URL(url); 

    var parser = new URL(toRequest); 

    console.log("if",parser.host,parser2.host,parser.host === parser2.host); 
    if(parser.host === parser2.host) { 
    toRequest = toRequest.replace('https://booligoosh.github.io',parser3.protocol + '//' + parser3.host); 
    console.log("ifdone",toRequest); 
    } 

    console.log("toRequest:",toRequest); 

    event.respondWith(httpGet('https://cors-anywhere.herokuapp.com/' + toRequest)); 
    }); 
}); 

function httpGet(theUrl) { 
    /*var xmlHttp = new XMLHttpRequest(); 
    xmlHttp.open("GET", theUrl, false); // false for synchronous request 
    xmlHttp.send(null); 
    return xmlHttp.responseText;*/ 
    return(fetch(theUrl)); 
} 

아무 도움이됩니다.

답변

2

문제는 event.respondWith()에 대한 호출이 최상위 약속의 .then() 절 안에 있다는 것입니다. 즉, 최상위 약속이 해결 된 후에 비동기 적으로 실행됩니다. 기대하는 동작을 얻으려면 event.respondWith()fetch 이벤트 처리기의 실행 중 일부로서 동 기적으로 실행해야합니다.

약속의 내부 논리는 따라하기 조금 어렵다, 그래서 당신이 달성하기 위해 노력하고 정확히 모르겠지만, 일반적으로이 패턴을 따를 수 :

self.addEventListerner('fetch', event => { 
    // Perform any synchronous checks to see whether you want to respond. 
    // E.g., check the value of event.request.url. 
    if (event.request.url.includes('something')) { 
    const promiseChain = doSomethingAsync() 
     .then(() => doSomethingAsyncThatReturnsAURL()) 
     .then(someUrl => fetch(someUrl)); 
     // Instead of fetch(), you could have called caches.match(), 
     // or anything else that returns a promise for a Response. 

    // Synchronously call event.respondWith(), passing in the 
    // async promise chain. 
    event.respondWith(promiseChain); 
    } 
}); 

입니다 일반적인 생각. 약속을 async/await으로 대체하면 코드가 더 깨끗해집니다.