我对JavaScript和承诺都很陌生,说实话,我并不完全理解承诺是如何运作的,所以我需要一些帮助。
我正在使用Google Cloud Messaging将通知从我的网站推送给我的用户。当用户收到通知并单击它时,它会打开存储在IndexedDB中的URL。
MissingMethodException: UnityScript.Lang.Array.IndexOf
Boo.Lang.Runtime.DynamicDispatching.MethodDispatcherFactory.ProduceExtensionDispatcher ()
Boo.Lang.Runtime.DynamicDispatching.MethodDispatcherFactory.Create ()
Boo.Lang.Runtime.RuntimeServices.DoCreateMethodDispatcher(System.Object target, System.Type targetType, System.String name, System.Object[] args)
Boo.Lang.Runtime.RuntimeServices.CreateMethodDispatcher (System.Object target, System.String name, System.Object[] args)
所以在上面的代码中,我知道getIdb()... then()是一个promise,但event.waitUntil也是一个承诺吗?
上述代码的问题在于,每次点击通知时都会打开Chrome的一个实例,我希望它会利用现有的实例(如果可用)。以下是:
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);
}));
});
但是,现在我有两个promise,getIdb和clients.matchAll,我真的不知道如何组合两个promises和两组代码。任何帮助将不胜感激。谢谢!
供参考,这里是IndexDBWrapper.js:
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('/');
}
})
);
});
答案 0 :(得分:8)
event.waitUntil()
接受承诺 - 这允许浏览器让您的工作人员保持活力,直到您完成了您想要做的事情(即直到您对event.waitUntil()
的承诺得到解决)
正如另一个答案所示,您可以在Promise.all()
中使用event.waitUntil
。 Promise.all()
获取一系列承诺并返回一个承诺,因此您可以在其上调用then
。当您提供给Promise.all
的所有承诺都已解决时,您的处理功能将获得一系列承诺结果。您的代码看起来会像这样(我还没有对此进行过测试,但它应该接近):
self.addEventListener('notificationclick', function (event) {
event.notification.close();
event.waitUntil(Promise.all([
getIdb().get(KEY_VALUE_STORE_NAME, event.notification.tag),
clients.matchAll({ type: "window" })
]).then(function (resultArray) {
var url = resultArray[0] || "/";
var clientList = resultArray[1];
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(url);
}
}));
});
答案 1 :(得分:5)
处理多项承诺的一种方法是使用Promise.all
Promise.all([promise0, promise1, promise2]).then(function(valArray) {
// valArray[0] is result of promise0
// valArray[1] is result of promise1
// valArray[2] is result of promise2
});
阅读promise.all - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all