javascript - 如何在循环中使用 Promises 并确保在继续之前都已完成?

标签 javascript loops promise es6-promise

我正在使用 localforage 库访问 localStorage/IndexedDB。要检索项目,将调用 localforage.getItem() 函数,该函数返回一个 Promise,该 Promise 在检索数据时实现。

我需要遍历 localforage 键,对符合我的条件的任何键调用“getItem”,并将该键的值放入“匹配”数组中。但是,在确定所有值已成功添加到“匹配项”之前,我不想继续该功能。

我是 Promises 的新手,我不知道如何等到所有 getItem() Promise 都完成后再继续。

我知道 localforage 有一个“迭代”功能,但我真的很想更熟练地使用 Promises,并且真的很想知道它应该如何工作。

这是我正在做的:

var matches = [];  // Array to store matched items

localforage.keys()  // Get all keys in localforage
    .then(function(keys)  // When all keys are retrieved, iterate:
    {
        for(var i in keys)
        {
            // If the current key matches what I am looking for, add it to the 'matches' array.
            if (keys[i].indexOf('something i am looking for') > -1)
            {
                // Here I need to add this value to my array 'matches', but this requires using the getItem method which returns a Promise and doesn't necessarily fulfill immediately.
                localforage.getItem(keys[i])
                    .then(function(value)
                    {
                        matches.push(value);
                    });
              }
          }
      });

// At this point, I want to proceed only after *all* matches have been added to the 'matches' array (i.e. the getItem() Promises are fulfilled on all items in the loop).

我该怎么做?这是应用“等待”表达式的地方吗?例如,我应该怎么做

await localforage.getItem(keys[i])
    .then(function(value)
    ... etc

这会使 getItem 函数同步吗?

感谢您的任何建议/指点。

最佳答案

在这种情况下,您可以使用 Promise.all()。基本思想是将一堆 promise 插入数组,然后将该数组传递给 Promise.all(),当数组中的所有 promise 解析时,Promise.all() 解析为值数组:

localforage.keys()  
    .then(function(keys){  
        var matches = []
        for(let i in keys) {
            if (keys[i].indexOf('something i am looking for') > -1) {
                // matches will be an array of promises
                matches.push(localforage.getItem(keys[i]))
            }
        }
        // Promise.all returns a promise that resolves to an array 
        // of the values they resolve to
        return Promise.all(matches)
    })
    .then(values => {
        // values is an array of your items
    })

您也可以为此使用 async/await,通过模拟 keysgetItems 来运行代码段:

let localforage = {
  keys() {
    return Promise.resolve([1, 2, 3, 4, 5])
  },
  getItem(k) {
    return Promise.resolve("found: " + k)
  }
}


async function getStuff() {
  let matches = []
  let keys = await localforage.keys()
  for (let key of keys) {
    matches.push(await localforage.getItem(key))
  }
  return matches
}

getStuff()
  .then(values => {
    console.log(values)
  })

关于javascript - 如何在循环中使用 Promises 并确保在继续之前都已完成?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50027407/

相关文章:

javascript - 想要在另一个div ng-if中引用ng-repeat中的变量。 AngularJS

javascript - 如何在可滚动的 div 中创建图像

python - 遍历列以切片数据集

javascript - 为什么 Sequelize 中会返回 Promise

mysql - 显示信息。使用 nodeJS 从 mySQL 数据库到网页

javascript - Golang 和 JavaScript 模块

java - 为什么我的方法不能正确重绘?

Python:为列表中的所有元素添加相同的前缀

JavaScript 嵌套 Promise 范围和 AngularJS

javascript - Object.length 在 javascript 中未定义