嵌套承诺-使用Dexie进行IndexedDB事务

时间:2019-01-24 00:13:31

标签: javascript promise indexeddb 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

            });
        }); 
    });

3 个答案:

答案 0 :(得分:1)

给予Collection.modify()的回调必须同步更新项目。您也可以使用anyOf()而不是等号来优化查询。这是一个体现另一种策略的示例:

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

答案 1 :(得分:1)

考虑到@David Fahlander的回答,Collection.modify()必须同步更新项目,因此您应该先收集异步响应,然后再更改数据库。您可以使用Promise.all()异步收集来自invokePromise的响应,然后再进行一次数据库修改。

答案 2 :(得分:1)

您可以检索所有条目,等待承诺,然后分别更新它们:

 (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.mapPromise.allTable.putAll并行化。