在执行 get 后跟 put 时,我应该使用单个事务吗?

Should I use a single transaction when doing a get followed by a put?

有人可能会说将单个函数嵌套在另一个函数中并不是回调地狱,但我正在尝试习惯将函数拉到其他函数之外,以避免不可避免的情况。

这是 .get/.put 的示例。我的问题与交易有关。我应该将其放入单笔交易中吗?

我不想执行 .get(myid).onsuccess=function() {}

init()
function init() {
 var myTransaction = myDatabase.transaction(['myData'],'readwrite')
 var myObjectStore = myTransaction.objectStore('myData')
 var myRequest = myObjectStore.get(myid)
 var myValue = 0
 var myUpdate = update.bind(this,myid,myValue)
 myRequest.onsuccess = myUpdate
}
function update(argid,argValue,response) {
 var obj = response.target.result
 obj.myField = argValue
 var myTransaction = myDatabase.transaction(['myData'],'readwrite')
 var myObjectStore = myTransaction.objectStore('myData')
 myObjectStore.put(obj,argid) // todo: onsuccess & onerror
}

使用单个事务的原因包括 (1) 方便和 (2) 数据完整性。完整性是指如果事务请求集中的一个请求失败,则所有请求都应该失败。

您在这里似乎最关心的是便利性,但您并不十分清楚您认为代码风格最方便的是什么。

如果您想要真正的方便,请考虑打开游标并使用 cursor.update 而不是显式的 get 和 put。虽然游标通常用于遍历多个对象,但仅使用游标来抓取一个对象本身并没有错。事实上,这或多或少就是 get 函数在幕后所做的。

如果你想避免嵌套,使用Function.prototype.bind即可。

绑定和使用示例 cursor.update:

function getAndPut(db, id) {
  var tx = db.transaction(..., 'readwrite');
  var store = tx.objectStore(...);
  var request = store.openCursor(id);
  request.onsuccess = getAndPutOnSuccess.bind(request, id);
}

function getAndPutOnSuccess(id, event) {
  var cursor = event.target.result;
  if(!cursor) {
    console.log('did not find object with id', id);
    return;
  }
  // Get the object at the cursor's current position
  var obj = cursor.value;

  // Edit the object
  obj.prop1 = 'foo';
  obj.prop2 = 'bar';

  // 'put' the new object back, overwriting the old object
  cursor.update(obj);
}

游标绑定到一个事务;特别是用于打开游标的事务。 cursor.update 隐式使用相同的事务。这主要是为了方便。