#javascript #indexeddb
#javascript #indexeddb
Вопрос:
Я использую библиотеку idbKeyval для сохранения / извлечения данных из локального хранилища IndexedDB. У меня есть функция для перебора всех моих ключей и получения каждого соответствующего объекта. Однако, когда я извлекаю каждый объект ( val
), мне нужно знать соответствующий ему ключ (именно так я соотношу объект с элементом в DOM). Но поскольку api IndexedDB (и idbKeyval) является асинхронным, я теряю ссылку на соответствующий ключ. Есть ли способ, которым я могу получить соответствующий, key
когда я получаю свой val
? Ниже приведен фрагмент, который лучше описывает то, что я пытаюсь сделать:
var customStore = new idbKeyval.Store('my-db', 'offline-transactions');
idbKeyval.keys(customStore)
.then(function (keys) {
for (var i in keys) {
var key = keys[i];
var val = idbKeyval.get(key, customStore)
.then(function (val) {
//THIS WORKS:
console.log(val);
//THIS DOES NOT WORK:
console.log(key);
//'KEY' IS OUT OF SCOPE HERE
//WHAT IS A GOOD WAY TO GET THE CORRESPONDING KEY FOR MY VAL HERE?
});
}
});
И я использую библиотеку idbKeyval:https://github.com/jakearchibald/idb-keyval
Ответ №1:
Существуют два три решения для этого. Вы можете либо создать IIFE (старым способом), либо установить локальную переменную для «копирования» переменной из вашего цикла:
.then(function(val) {
(() => {
var localKey = key;
// ...
// localKey will be preserved since it's encapsulated
// in its own functional scope
})();
}
Или вы можете использовать более элегантный Array.forEach
метод ES6:
keys.forEach((key) => {
var val = // ...
// No need to copy key here since we're in a new functional
// scope by the nature of .forEach
});
Оба метода по сути работают одинаково — вы сохраняете переменную, создавая новую функциональную область для каждой итерации вашего цикла.
Надеюсь, это поможет немного прояснить ситуацию.
Редактировать
Я пропустил самое простое * решение: использование let
or const
в вашем цикле for вместо var
. Это работает, потому что let
и const
имеют область блока вместо области функции. Эта статья помогает объяснить это. Итак:
for (var i in keys) {
const key = keys[i];
// ...
// key will be preserved in block
}
Лично я предпочел бы Array.forEach
просто потому, что это выглядит проще и защищает вас от необходимости беспокоиться о том, в какой области вы находитесь.
* Самый простой: я понятия не имел до недавнего времени.