2017-08-10 23 views
7

Trong một trong những ví dụ dịch vụ Worker bởi Google, cache and return requestsTại sao yêu cầu tìm nạp phải được nhân bản trong nhân viên dịch vụ?

self.addEventListener('fetch', function(event) { 
    event.respondWith(
    caches.match(event.request) 
     .then(function(response) { 
     // Cache hit - return response 
     if (response) { 
      return response; 
     } 

     // IMPORTANT: Clone the request. A request is a stream and 
     // can only be consumed once. Since we are consuming this 
     // once by cache and once by the browser for fetch, we need 
     // to clone the response. 
     var fetchRequest = event.request.clone(); 

     return fetch(fetchRequest).then(
      function(response) { 
      // Check if we received a valid response 
      if(!response || response.status !== 200 || response.type !== 'basic') { 
       return response; 
      } 

      // IMPORTANT: Clone the response. A response is a stream 
      // and because we want the browser to consume the response 
      // as well as the cache consuming the response, we need 
      // to clone it so we have two streams. 
      var responseToCache = response.clone(); 

      caches.open(CACHE_NAME) 
       .then(function(cache) { 
       cache.put(event.request, responseToCache); 
       }); 

      return response; 
      } 
     ); 
     }) 
    ); 
}); 

Mặt khác, ví dụ được cung cấp bởi MDN, Using Service Workers, không sao chép theo yêu cầu.

this.addEventListener('fetch', function(event) { 
    event.respondWith(
    caches.match(event.request).then(function(resp) { 
     return resp || fetch(event.request).then(function(response) { 
     caches.open('v1').then(function(cache) { 
      cache.put(event.request, response.clone()); 
     }); 
     return response; 
     }); 
    }).catch(function() { 
     return caches.match('/sw-test/gallery/myLittleVader.jpg'); 
    }) 
); 
}); 

Vì vậy, trong trường hợp của một cache trong ví dụ của Google:

Tôi hiểu lý do tại sao chúng ta phải sao chép câu trả lời: bởi vì nó được tiêu thụ bởi cache.put, và chúng tôi vẫn muốn trả lại trả lời lại trang web đã yêu cầu.

Nhưng tại sao người ta phải sao chép yêu cầu? Trong nhận xét, nó cho biết nó được tiêu thụ bởi bộ nhớ cachetrình duyệt để tìm nạp. điều đó có chính xác?

  • Vị trí trong bộ nhớ cache là luồng yêu cầu tiêu thụ? cache.put? Nếu vậy, tại sao không caches.match tiêu thụ yêu cầu?

Trả lời

1

Các bình luận dường như tôi nói khá rõ ràng lý do tại sao tác giả của mã mà nghĩ nhân bản là cần thiết:

Một yêu cầu là một dòng suối và chỉ có thể được tiêu thụ một lần. Vì chúng tôi đang sử dụng bộ nhớ cache này một lần và một lần bởi trình duyệt để tìm nạp, chúng tôi cần sao chép phản hồi.

Hãy nhớ rằng yêu cầu body của yêu cầu có thể là ReadableStream. Nếu cache.match phải đọc luồng (hoặc đọc một phần luồng) để biết liệu mục nhập bộ nhớ cache có phù hợp hay không, thì đọc tiếp theo fetch sẽ tiếp tục đọc, thiếu bất kỳ dữ liệu nào mà đọc cache.match.

Tôi sẽ không ngạc nhiên nếu nó chỉ quan trọng trong các tình huống hạn chế (trừ khi mã trong ví dụ của Google chỉ đơn giản là sai và không cần thiết), và do đó không thực hiện nó có thể hoạt động trong nhiều trường hợp thử nghiệm (ví dụ , trong đó nội dung là null hoặc một chuỗi, không phải luồng). Hãy nhớ rằng MDN là rất tốt, nhưng nó cộng đồng chỉnh sửa, và các lỗi và ví dụ nghèo làm creep theo định kỳ. (Tôi đã phải sửa một số lỗi trắng trợn trong đó trong nhiều năm.) Thông thường cộng đồng sẽ phát hiện ra chúng và sửa chúng.

+1

Các đoạn mã trên trang web cơ bản của nhà phát triển web google, khác nhau về triển khai. ví dụ, Jake doen't sao chép yêu cầu [ở đây] (https://developers.google.com/web/fundamentals/instant-and-offline/offline-cookbook/#on-network-response) –

+0

@ Schrodinger'scat : Heh, nhưng vẫn nói bên dưới mã đó: * "Để cho phép sử dụng bộ nhớ hiệu quả, bạn chỉ có thể đọc nội dung phản hồi/yêu cầu một lần. Trong đoạn mã trên, .clone() được sử dụng để tạo các bản sao bổ sung có thể đọc riêng . "* (lưu ý *" ... phản hồi/yêu cầu của cơ thể một lần ... "*). Tôi thực sự không thể nói từ thông số kỹ thuật của nhân viên dịch vụ, trong vài phút tôi đã cho nó, cho dù bạn có cần hay không. Tôi đoán là bạn làm, * nếu * cơ thể của yêu cầu là một luồng. Tôi có thể thử nghiệm nó để chắc chắn (và thậm chí sau đó, tôi thực sự chỉ biết nếu nó * thất bại *). –

+0

hmm .. tốt hơn là thông số của nhân viên dịch vụ, tôi đoán điều này có thể được ghi lại trong thông số cache hoặc lấy thông số api spec .. cần đọc –

0

fetch yêu cầu, không được lưu trữ và do đó caches không chủ yếu tiêu thụ một request

Do đó, không cần phải sao chép. - asked Jake on his write up earlier.

responses tuy nhiên, put hoặc added thành một bộ nhớ cache và/hoặc, có thể được truyền xuống chuỗi then như JSON/text/cái gì khác - ý nghĩa, họ là/có thể được tiêu thụ.

Đoán của tôi là, Nếu bạn hãy sử dụng hoặc biến đổi một cái gì đó, sau đó, bạn cần sao chép nó.

Một read là có thể làm cả trong caches.match

Tôi cũng giả định, đó có thể là một lý do khác là, đọc theo yêu cầu riêng của mình, không phải là piped xuống chuỗi, và chỉ được đọc một lần bởi caches.match như trong , việc đọc chỉ xảy ra một lần, nhưng luồng phản hồi, có thể được chuyển vào các đường ống biến đổi/chuyển đổi/ghi khác

Chỉ cần nắm bắt từ luồng đặc tả. cho các chuyên gia

Vì vậy, nếu tôi đã diễn giải sự hiểu biết của tôi cho đến bây giờ, hãy sao chép những gì lý tưởng là tiêu thụ và không bận tâm khác. Và trong trường hợp này, chính bản thân đọc, không làm thay đổi yêu cầu/ghi nó ở nơi khác, do đó không cần phải sao chép

Các vấn đề liên quan