嵌套承诺 - 使用 Dexie 的 IndexedDB 事务
Nested promises - IndexedDB transactions using Dexie
我有以下代码,其中基于内部承诺修改数据库项不起作用。
$('input[type=checkbox][name=checklist]:checked').each(function()
{
var collection=db.items.where("name").equals(checkbox.val());
var success;
collection.modify(function(item){
var invokePromise;
//invokePromise = a fucntion that returns a promise
//this invokepromise function needs the item from the db.
invokePromise.then(function(thirdPartyResponse){
item.date=new Date();
item.attempts= item.attempts+1; <-- this is not being updated.
}).catch(function(error){
delete this.value; <-- this is also not deleted
});
});
});
给 Collection.modify() 的回调必须同步更新项目。您还可以使用 anyOf() 而不是 equasls 来优化查询。下面是另一个策略的示例:
function yourAction () {
const checkedValues = $('input[type=checkbox][name=checklist]:checked')
.toArray() // Convert to a standard array of elements
.map(checkBox => checkBox.value); // Convert to an array of checked values
return invokePromise.then(thirdPartyResponse => {
return db.items.where("name").anyOf(checkedValues).modify(item => {
item.date = new Date();
++item.attempts;
}).catch(error => {
console.error("Failed to update indexedDB");
throw error;
});
}).catch(error => {
// Handle an errors from invokePromise
// If an error occurs, delete the values. Was this your intent?
console.error("Error occurred. Now deleting values instead", error);
return db.items.where("name").anyOf(checkedValues).delete();
});
}
正在考虑 @David Fahlander answer that Collection.modify()
must synchronously update the item, you should collect the async responses first and after alter the database. You can use Promise.all() 异步收集来自 invokePromise
的响应,然后一次性修改数据库。
您可以检索所有条目,等待承诺,然后单独更新它们:
(async function() {
const entries = await db.items
.where("name").equals(checkbox.val())
.toArray();
for(const entry of entries) {
//...
await invokePromise;
await db.items.put(entry);
}
})();
您可能希望将整个事情与 entries.map
和 Promise.all
以及 Table.putAll
并行化。
我有以下代码,其中基于内部承诺修改数据库项不起作用。
$('input[type=checkbox][name=checklist]:checked').each(function()
{
var collection=db.items.where("name").equals(checkbox.val());
var success;
collection.modify(function(item){
var invokePromise;
//invokePromise = a fucntion that returns a promise
//this invokepromise function needs the item from the db.
invokePromise.then(function(thirdPartyResponse){
item.date=new Date();
item.attempts= item.attempts+1; <-- this is not being updated.
}).catch(function(error){
delete this.value; <-- this is also not deleted
});
});
});
给 Collection.modify() 的回调必须同步更新项目。您还可以使用 anyOf() 而不是 equasls 来优化查询。下面是另一个策略的示例:
function yourAction () {
const checkedValues = $('input[type=checkbox][name=checklist]:checked')
.toArray() // Convert to a standard array of elements
.map(checkBox => checkBox.value); // Convert to an array of checked values
return invokePromise.then(thirdPartyResponse => {
return db.items.where("name").anyOf(checkedValues).modify(item => {
item.date = new Date();
++item.attempts;
}).catch(error => {
console.error("Failed to update indexedDB");
throw error;
});
}).catch(error => {
// Handle an errors from invokePromise
// If an error occurs, delete the values. Was this your intent?
console.error("Error occurred. Now deleting values instead", error);
return db.items.where("name").anyOf(checkedValues).delete();
});
}
正在考虑 @David Fahlander answer that Collection.modify()
must synchronously update the item, you should collect the async responses first and after alter the database. You can use Promise.all() 异步收集来自 invokePromise
的响应,然后一次性修改数据库。
您可以检索所有条目,等待承诺,然后单独更新它们:
(async function() {
const entries = await db.items
.where("name").equals(checkbox.val())
.toArray();
for(const entry of entries) {
//...
await invokePromise;
await db.items.put(entry);
}
})();
您可能希望将整个事情与 entries.map
和 Promise.all
以及 Table.putAll
并行化。