La combinaison de deux promesses
Je suis vraiment nouveau dans le JavaScript et les promesses, et pour être honnête, je n'ai pas de comprendre pleinement comment les promesses de travail donc j'ai besoin d'aide.
Je suis en utilisant Google Cloud Messaging pour les notifications push de mon site pour mes utilisateurs. Lorsque les utilisateurs reçoivent une notification et clique sur le lien, il s'ouvre une URL stockée dans un IndexedDB.
importScripts('IndexDBWrapper.js');
var KEY_VALUE_STORE_NAME = 'key-value-store', idb;
function getIdb() {
if (!idb) {
idb = new IndexDBWrapper(KEY_VALUE_STORE_NAME, 1, function (db) {
db.createObjectStore(KEY_VALUE_STORE_NAME);
});
}
return idb;
}
self.addEventListener('notificationclick', function (event) {
console.log('On notification click: ', event);
event.notification.close();
event.waitUntil(getIdb().get(KEY_VALUE_STORE_NAME, event.notification.tag).then(function (url) {
var redirectUrl = '/';
if (url) redirectUrl = url;
return clients.openWindow(redirectUrl);
}));
});
Donc, dans le code ci-dessus, je sais que le getIdb()...alors() est une promesse, mais c'est le cas.waitUntil aussi une promesse?
Le problème avec le code ci-dessus est qu'il ouvre une instance de Chrome à chaque fois que la notification est cliqué et je préfère qu'il ferait appel à une instance existante si elle est disponible. La suite est juste que:
self.addEventListener('notificationclick', function(event) {
console.log('On notification click: ', event.notification.tag);
event.notification.close();
event.waitUntil(
clients.matchAll({
type: "window"
})
.then(function(clientList) {
for (var i = 0; i < clientList.length; i++) {
var client = clientList[i];
if (client.url == '/' && 'focus' in client)
return client.focus();
}
if (clients.openWindow) {
return clients.openWindow('/');
}
})
);
});
Cependant, maintenant, j'ai deux promesses, getIdb et les clients.matchall peut et je n'ai vraiment aucune idée de la façon de combiner les deux promesses et les deux ensembles de code. Toute aide serait grandement appréciée. Merci!
Pour référence, voici IndexDBWrapper.js:
'use strict';
function promisifyRequest(obj) {
return new Promise(function(resolve, reject) {
function onsuccess(event) {
resolve(obj.result);
unlisten();
}
function onerror(event) {
reject(obj.error);
unlisten();
}
function unlisten() {
obj.removeEventListener('complete', onsuccess);
obj.removeEventListener('success', onsuccess);
obj.removeEventListener('error', onerror);
obj.removeEventListener('abort', onerror);
}
obj.addEventListener('complete', onsuccess);
obj.addEventListener('success', onsuccess);
obj.addEventListener('error', onerror);
obj.addEventListener('abort', onerror);
});
}
function IndexDBWrapper(name, version, upgradeCallback) {
var request = indexedDB.open(name, version);
this.ready = promisifyRequest(request);
request.onupgradeneeded = function(event) {
upgradeCallback(request.result, event.oldVersion);
};
}
IndexDBWrapper.supported = 'indexedDB' in self;
var IndexDBWrapperProto = IndexDBWrapper.prototype;
IndexDBWrapperProto.transaction = function(stores, modeOrCallback, callback) {
return this.ready.then(function(db) {
var mode = 'readonly';
if (modeOrCallback.apply) {
callback = modeOrCallback;
}
else if (modeOrCallback) {
mode = modeOrCallback;
}
var tx = db.transaction(stores, mode);
var val = callback(tx, db);
var promise = promisifyRequest(tx);
var readPromise;
if (!val) {
return promise;
}
if (val[0] && 'result' in val[0]) {
readPromise = Promise.all(val.map(promisifyRequest));
}
else {
readPromise = promisifyRequest(val);
}
return promise.then(function() {
return readPromise;
});
});
};
IndexDBWrapperProto.get = function(store, key) {
return this.transaction(store, function(tx) {
return tx.objectStore(store).get(key);
});
};
IndexDBWrapperProto.put = function(store, key, value) {
return this.transaction(store, 'readwrite', function(tx) {
tx.objectStore(store).put(value, key);
});
};
IndexDBWrapperProto.delete = function(store, key) {
return this.transaction(store, 'readwrite', function(tx) {
tx.objectStore(store).delete(key);
});
};
- Cela ressemble à
event.waitUntil
c'est une méthode qui prend une promesse. - merci pour l'astuce. Sachant que les noms réels de ces choses va m'aider grandement.
Vous devez vous connecter pour publier un commentaire.
event.waitUntil()
prend une promesse - cela permet au navigateur de garder votre travailleur en vie jusqu'à ce que vous avez terminé ce que vous voulez faire (c'est à dire jusqu'à ce que la promesse que vous avez donné àevent.waitUntil()
a résolu).Que les autres de répondre à l'indique, vous pouvez utiliser
Promise.all()
dansevent.waitUntil
.Promise.all()
prend un tableau de promesses et retourne une promesse, de sorte que vous pouvez appelerthen
sur elle. Votre fonction de gestion permettra d'obtenir un tableau de promettent des résultats lorsque toutes les promesses que vous avez fourniePromise.all
ont résolu. Votre code sera alors ressembler à quelque chose comme ça (je n'ai pas réellement testé, mais il devrait être proche):client.navigate(url)
méthode pour être mis en œuvre. Lorsqu'il est mis en œuvre, quelle est la meilleure façon de retourner les deuxclient.navigate(url)
etclient.focus()
?Un moyen de traiter avec de multiples promesses avec
Promise.all
lisez à propos de la promesse.tout https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all
Promise.all
prend un objet iterable (par exemple un tableau), mais pas plusieurs arguments