Combining two promises

event.waitUntil() takes a promise - this allows the browser to keep your worker alive until you've finished what you want to do (i.e. until the promise that you gave to event.waitUntil() has resolved).

As the other answer suggests, you can use Promise.all() within event.waitUntil. Promise.all() takes an array of promises and returns a promise, so you can call then on it. Your handling function will get an array of promise results when all of the promises you've provided to Promise.all have resolved. Your code will then look something like this (I haven't actually tested this, but it should be close):

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);
    }
  }));
});

One way to deal with multiple promises is with 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
});

read about promise.all - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all