Wanneer u gegevens naar een webserver verzendt, mislukken de verzoeken soms. Het kan zijn omdat de gebruiker de connectiviteit heeft verloren, of omdat de server niet beschikbaar is; in beide gevallen wilt u vaak proberen de verzoeken later opnieuw te verzenden.
De nieuwe BackgroundSync API is een ideale oplossing voor dit probleem. Wanneer een servicemedewerker detecteert dat een netwerkverzoek is mislukt, kan deze zich registreren voor het ontvangen van een sync
, die wordt afgeleverd wanneer de browser denkt dat de connectiviteit is hersteld. Houd er rekening mee dat de synchronisatiegebeurtenis zelfs kan worden afgeleverd als de gebruiker de applicatie heeft verlaten , waardoor deze veel effectiever is dan de traditionele methode voor het opnieuw proberen van mislukte verzoeken.
Workbox Background Sync is ontworpen om het gebruik van de BackgroundSync API eenvoudiger te maken en het gebruik ervan met andere Workbox-modules te integreren. Het implementeert ook een fallback-strategie voor browsers die BackgroundSync nog niet implementeren.
Browsers die de BackgroundSync API ondersteunen, zullen mislukte verzoeken automatisch namens u opnieuw afspelen met een interval dat wordt beheerd door de browser , waarbij waarschijnlijk gebruik wordt gemaakt van exponentiële vertraging tussen herhalingspogingen. In browsers die de BackgroundSync API niet standaard ondersteunen, probeert Workbox Background Sync automatisch opnieuw af te spelen wanneer uw servicemedewerker opstart.
Basisgebruik
De eenvoudigste manier om Achtergrondsynchronisatie te gebruiken is door de Plugin
te gebruiken die automatisch mislukte verzoeken in de wachtrij zet en deze opnieuw probeert wanneer toekomstige sync
worden geactiveerd.
import {BackgroundSyncPlugin} from 'workbox-background-sync';
import {registerRoute} from 'workbox-routing';
import {NetworkOnly} from 'workbox-strategies';
const bgSyncPlugin = new BackgroundSyncPlugin('myQueueName', {
maxRetentionTime: 24 * 60, // Retry for max of 24 Hours (specified in minutes)
});
registerRoute(
/\/api\/.*\/*.json/,
new NetworkOnly({
plugins: [bgSyncPlugin],
}),
'POST'
);
BackgroundSyncPlugin
haakt in op de fetchDidFail
plug-in callback en fetchDidFail
wordt alleen aangeroepen als er een uitzondering optreedt, hoogstwaarschijnlijk als gevolg van een netwerkfout. Dit betekent dat verzoeken niet opnieuw worden geprobeerd als er een antwoord wordt ontvangen met de foutstatus 4xx
of 5xx
. Als u alle verzoeken die resulteren in bijvoorbeeld een 5xx
status opnieuw wilt proberen, kunt u dit doen door een fetchDidSucceed
-plug-in aan uw strategie toe te voegen :
const statusPlugin = {
fetchDidSucceed: ({response}) => {
if (response.status >= 500) {
// Throwing anything here will trigger fetchDidFail.
throw new Error('Server error.');
}
// If it's not 5xx, use the response as-is.
return response;
},
};
// Add statusPlugin to the plugins array in your strategy.
Geavanceerd gebruik
Workbox Background Sync biedt ook een klasse Queue
, waaraan u mislukte verzoeken kunt instantiëren en eraan kunt toevoegen. De mislukte verzoeken worden opgeslagen in IndexedDB en opnieuw geprobeerd wanneer de browser denkt dat de connectiviteit is hersteld (dwz wanneer deze de synchronisatiegebeurtenis ontvangt).
Een wachtrij maken
Om een Workbox Background Sync Queue te maken, moet u deze construeren met een wachtrijnaam (die uniek moet zijn voor uw oorsprong ):
import {Queue} from 'workbox-background-sync';
const queue = new Queue('myQueueName');
De wachtrijnaam wordt gebruikt als onderdeel van de tagnaam die register()
-ed krijgt door de globale SyncManager
. Het wordt ook gebruikt als de Object Store- naam voor de IndexedDB-database.
Een verzoek aan de wachtrij toevoegen
Nadat u uw Queue-instantie heeft gemaakt, kunt u er mislukte verzoeken aan toevoegen. U voegt een mislukt verzoek toe door de methode .pushRequest()
aan te roepen. De volgende code vangt bijvoorbeeld alle aanvragen op die mislukken en voegt deze toe aan de wachtrij:
import {Queue} from 'workbox-background-sync';
const queue = new Queue('myQueueName');
self.addEventListener('fetch', event => {
// Add in your own criteria here to return early if this
// isn't a request that should use background sync.
if (event.request.method !== 'POST') {
return;
}
const bgSyncLogic = async () => {
try {
const response = await fetch(event.request.clone());
return response;
} catch (error) {
await queue.pushRequest({request: event.request});
return error;
}
};
event.respondWith(bgSyncLogic());
});
Zodra het verzoek aan de wachtrij is toegevoegd, wordt het automatisch opnieuw geprobeerd wanneer de servicemedewerker de sync
ontvangt (wat gebeurt wanneer de browser denkt dat de connectiviteit is hersteld). Browsers die de BackgroundSync API niet ondersteunen, zullen de wachtrij telkens opnieuw proberen wanneer de servicemedewerker wordt opgestart. Hiervoor moet de pagina die de servicemedewerker bestuurt actief zijn, dus het zal niet zo effectief zijn.
Workbox-achtergrondsynchronisatie testen
Helaas is het testen van BackgroundSync om een aantal redenen enigszins onintuïtief en moeilijk.
De beste aanpak om uw implementatie te testen is door het volgende te doen:
- Laad een pagina en registreer uw servicemedewerker.
- Schakel het netwerk van uw computer uit of schakel uw webserver uit.
- GEBRUIK CHROME DEVTOOLS NIET OFFLINE. Het offline selectievakje in DevTools heeft alleen invloed op verzoeken van de pagina. Verzoeken van servicemedewerkers blijven binnenkomen.
- Maak netwerkverzoeken die in de wachtrij moeten worden geplaatst met Workbox Background Sync.
- U kunt controleren of de verzoeken in de wachtrij zijn geplaatst door te kijken in
Chrome DevTools > Application > IndexedDB > workbox-background-sync > requests
- U kunt controleren of de verzoeken in de wachtrij zijn geplaatst door te kijken in
- Schakel nu uw netwerk- of webserver in.
Forceer een vroege
sync
door naarChrome DevTools > Application > Service Workers
te gaan, de tagnaam vanworkbox-background-sync:<your queue name>
in te voeren, waarbij<your queue name>
de naam moet zijn van de wachtrij die u hebt ingesteld, en vervolgens door op de knop 'Synchroniseren' te klikken.U zou netwerkverzoeken moeten zien doorgaan voor de mislukte verzoeken en de IndexedDB-gegevens zouden nu leeg moeten zijn omdat de verzoeken met succes opnieuw zijn afgespeeld.
Soorten
BackgroundSyncPlugin
Een klasse die de levenscycluscallback fetchDidFail
implementeert. Dit maakt het eenvoudiger om mislukte verzoeken toe te voegen aan een wachtrij voor synchronisatie op de achtergrond.
Eigenschappen
- bouwer
leegte
De
constructor
ziet er als volgt uit:(name: string, options?: QueueOptions) => {...}
- naam
snaar
Zie de
workbox-background-sync.Queue
-documentatie voor parameterdetails. - opties
Wachtrijopties optioneel
- retourneert
Queue
Een klasse voor het beheren van het opslaan van mislukte aanvragen in IndexedDB en het later opnieuw proberen ervan. Alle delen van het opslag- en afspeelproces zijn waarneembaar via callbacks.
Eigenschappen
- bouwer
leegte
Creëert een exemplaar van Queue met de gegeven opties
De
constructor
ziet er als volgt uit:(name: string, options?: QueueOptions) => {...}
- naam
snaar
De unieke naam voor deze wachtrij. Deze naam moet uniek zijn, omdat deze wordt gebruikt om synchronisatiegebeurtenissen te registreren en verzoeken op te slaan in IndexedDB die specifiek zijn voor deze instantie. Er wordt een fout gegenereerd als er een dubbele naam wordt gedetecteerd.
- opties
Wachtrijopties optioneel
- retourneert
- naam
snaar
- krijg alles
leegte
Retourneert alle vermeldingen die niet zijn verlopen (per
maxRetentionTime
). Alle verlopen vermeldingen worden uit de wachtrij verwijderd.De
getAll
functie ziet er als volgt uit:() => {...}
- retourneert
Beloof<QueueEntry[]>
- popAanvraag
leegte
Verwijdert en retourneert het laatste verzoek in de wachtrij (samen met de tijdstempel en eventuele metagegevens). Het geretourneerde object heeft de vorm:
{request, timestamp, metadata}
.De
popRequest
functie ziet er als volgt uit:() => {...}
- retourneert
Belofte<QueueEntry>
- pushRequest
leegte
Slaat het doorgegeven verzoek op in IndexedDB (met zijn tijdstempel en eventuele metagegevens) aan het einde van de wachtrij.
De
pushRequest
functie ziet er als volgt uit:(entry: QueueEntry) => {...}
- binnenkomst
Wachtrijinvoer
- retourneert
Beloof <nietig>
- registerSync
leegte
Registreert een synchronisatiegebeurtenis met een tag die uniek is voor deze instantie.
De
registerSync
functie ziet er als volgt uit:() => {...}
- retourneert
Beloof <nietig>
- herhaalverzoeken
leegte
Doorloopt elk verzoek in de wachtrij en probeert het opnieuw op te halen. Als een verzoek niet opnieuw kan worden opgehaald, wordt het teruggezet op dezelfde positie in de wachtrij (wat een nieuwe poging registreert voor de volgende synchronisatiegebeurtenis).
De
replayRequests
functie ziet er als volgt uit:() => {...}
- retourneert
Beloof <nietig>
- shiftRequest
leegte
Verwijdert en retourneert het eerste verzoek in de wachtrij (samen met de tijdstempel en eventuele metagegevens). Het geretourneerde object heeft de vorm:
{request, timestamp, metadata}
.De
shiftRequest
functie ziet er als volgt uit:() => {...}
- retourneert
Belofte<QueueEntry>
- maat
leegte
Retourneert het aantal vermeldingen in de wachtrij. Houd er rekening mee dat verlopen vermeldingen (per
maxRetentionTime
) ook in deze telling worden opgenomen.De
size
ziet er als volgt uit:() => {...}
- retourneert
Beloof<nummer>
- unshiftRequest
leegte
Slaat het doorgegeven verzoek op in IndexedDB (met zijn tijdstempel en eventuele metagegevens) aan het begin van de wachtrij.
De
unshiftRequest
functie ziet er als volgt uit:(entry: QueueEntry) => {...}
- binnenkomst
Wachtrijinvoer
- retourneert
Beloof <nietig>
QueueOptions
Eigenschappen
- forceSyncFallback
Booleaans optioneel
- maxRetentieTijd
nummer optioneel
- onSync
OnSyncCallback optioneel
QueueStore
Een klasse voor het beheren van het opslaan van aanvragen uit een wachtrij in IndexedDB, geïndexeerd op basis van hun wachtrijnaam voor eenvoudigere toegang.
De meeste ontwikkelaars hebben geen rechtstreekse toegang tot deze klasse nodig; het is beschikbaar voor geavanceerde gebruiksscenario's.
Eigenschappen
- bouwer
leegte
Koppelt dit exemplaar aan een wachtrij-exemplaar, zodat toegevoegde vermeldingen kunnen worden geïdentificeerd aan de hand van hun wachtrijnaam.
De
constructor
ziet er als volgt uit:(queueName: string) => {...}
- wachtrijNaam
snaar
- retourneert
- verwijderInvoer
leegte
Verwijdert de vermelding voor de opgegeven ID.
WAARSCHUWING: deze methode garandeert niet dat het verwijderde item tot deze wachtrij behoort (dwz overeenkomt met de
queueName
). Maar deze beperking is acceptabel omdat deze klasse niet openbaar wordt gemaakt. Een extra controle zou deze methode langzamer maken dan nodig is.De
deleteEntry
functie ziet er als volgt uit:(id: number) => {...}
- Identiteitskaart
nummer
- retourneert
Beloof <nietig>
- krijg alles
leegte
Retourneert alle vermeldingen in de winkel die overeenkomen met de
queueName
.De
getAll
functie ziet er als volgt uit:() => {...}
- retourneert
Beloof<QueueStoreEntry[]>
- popEntry
leegte
Verwijdert en retourneert de laatste vermelding in de wachtrij die overeenkomt met de
queueName
.De
popEntry
functie ziet er als volgt uit:() => {...}
- retourneert
Belofte<QueueStoreEntry>
- pushEntry
leegte
Voeg een item als laatste in de wachtrij toe.
De
pushEntry
functie ziet er als volgt uit:(entry: UnidentifiedQueueStoreEntry) => {...}
- binnenkomst
Niet-geïdentificeerdeQueueStoreEntry
- retourneert
Beloof <nietig>
- shiftEntry
leegte
Verwijdert en retourneert de eerste vermelding in de wachtrij die overeenkomt met de
queueName
.De
shiftEntry
functie ziet er als volgt uit:() => {...}
- retourneert
Belofte<QueueStoreEntry>
- maat
leegte
Retourneert het aantal vermeldingen in het archief dat overeenkomt met de
queueName
.De
size
ziet er als volgt uit:() => {...}
- retourneert
Beloof<nummer>
- unshiftEntry
leegte
Plaats een vermelding als eerste in de wachtrij.
De
unshiftEntry
functie ziet er als volgt uit:(entry: UnidentifiedQueueStoreEntry) => {...}
- binnenkomst
Niet-geïdentificeerdeQueueStoreEntry
- retourneert
Beloof <nietig>
StorableRequest
Een klasse waarmee u eenvoudiger aanvragen kunt serialiseren en deserialiseren, zodat ze kunnen worden opgeslagen in IndexedDB.
De meeste ontwikkelaars hebben geen rechtstreekse toegang tot deze klasse nodig; het is beschikbaar voor geavanceerde gebruiksscenario's.
Eigenschappen
- bouwer
leegte
Accepteert een object met aanvraaggegevens die kunnen worden gebruikt om een
Request
samen te stellen, maar die ook kunnen worden opgeslagen in IndexedDB.De
constructor
ziet er als volgt uit:(requestData: RequestData) => {...}
- verzoekGegevens
Gegevens aanvragen
Een object met aanvraaggegevens dat de
url
plus eventuele relevante eigenschappen van [requestInit]https://fetch.spec.whatwg.org/#requestinit
bevat.
- retourneert
- kloon
leegte
Creëert en retourneert een diepe kloon van de instantie.
De
clone
ziet er als volgt uit:() => {...}
- retourneert
- naarBezwaar
leegte
Retourneert een diepe kloon van het instance-object
_requestData
.De
toObject
functie ziet er als volgt uit:() => {...}
- retourneert
Gegevens aanvragen
- naarAanvragen
leegte
Converteert deze instantie naar een verzoek.
De
toRequest
functie ziet er als volgt uit:() => {...}
- retourneert
Verzoek
- vanAanvraag
leegte
Converteert een Request-object naar een gewoon object dat gestructureerd kan worden gekloond of JSON-stringified.
De
fromRequest
functie ziet er als volgt uit:(request: Request) => {...}
- verzoek
Verzoek
- retourneert
Belofte <StorableRequest>