只有当第一个没有返回好的结果时才执行其他承诺

Execute other promise only if first one didn't returned good results

因此,我为此苦苦挣扎了几天,并且找到了解决方案,但我觉得这不是一个好的解决方案。 我目前有以下内容。我不喜欢它,因为我在承诺中嵌套了承诺。我不知道这样好不好,但看起来不像。

我试图用这段代码完成的是首先检查缓存数据库中的值,如果它不存在,然后我将检查真实的数据库。

任何tips/tricks/pointers/comments关于如何更优雅地做到这一点?

var getData = function() {
    var cancel = false
    var cache = db.getFromCache(query)
      .then((data) => {
      // Check if data is up to date
         if (uptodate) { 
            return Promise.resolve(data) 
         }
         cancel = true      
       })

   return cache
        .then(() => {
          if (cancel)
             return db.getFromDatabase().then( //code)
    }
}

ps:这段代码可能会也可能不会 运行 我只是很快就回答了这个问题。我无法通过这里的真实代码

Promises 支持链接,这意味着一个 promise 可以 return 另一个 promise,这个可以 return 另一个,依此类推。

根据MDN

  1. You can pass a lambda (anonymous function) to then and if it returns a promise, an equivalent Promise will be exposed to the subsequent then in the method chain.
  2. When a value is simply returned from within a then lambda, it will effectively return Promise.resolve().

这意味着在 then 块中,您可以检查缓存中的 data 是否是最新的。如果 data 是新鲜的 return 它,值将被包装在一个新的承诺中。如果数据过时,您可以 return 调用 getFromDatabase(),return 承诺:

const getData = (query) => db.getFromCache(query)
    .then((data) => isUpToDate(data) ? data : db.getFromDatabase(query));

getData().then(/** code **/);

从 promise 返回用新的 promise 包装 returned 数据,因此您可以操作数据,return 它,它会自动被 promise 包装:

db.getFromDatabase().then((data) => data.map(/** some code **/)); // result will be wrapped in a promise.

当您在 .then() 处理程序中时,您可以执行以下任一操作:

  1. Return 一个值 - 该值成为父承诺的解析值。所以,没必要returnPromise.resolve(value)。你可以 return value.

  2. Return 一个 promise - 当你 return 一个 promise 时,它​​被链接到父 promise 并且父 promise 将在这个新承诺解决之前不会解决,并且这个 returned 承诺的解决值将成为父承诺的解决值。

  3. 抛出异常 - 如果 .then() 处理程序抛出异常,该异常会被 promise 基础设施自动捕获并转化为拒绝,因此throw errreturn Promise.reject(err).

  4. 的工作方式类似

因此,当您在 .then() 处理程序中时,您可以只检查缓存数据是否有效,如果有效,就 return 它。否则,return 获取数据的新承诺。

var getData = function() {
    return db.getFromCache(query).then((data) => {
         // Check if data is up to date
         if (uptodate) { 
            // return cached data, will be resolved value of promise
            return data; 
         } else {
            // get data from db, return promise that will be chained
            return db.getFromDatabase();
         }
   })
}

getData().then(...)

您的代码比需要的复杂得多:

  1. 你不需要Promise.resolve()。您可以 return 值。
  2. 您根本不需要 cancel 变量。您可以在第一个 .then() 处理程序中完成所有工作。
  3. 您不需要第二个 .then() 处理程序。