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

时间:2017-01-13 17:42:52

标签: indexeddb

有人可以说,将一个函数嵌套在另一个函数中的论点不是回调地狱,但我试图习惯于将函数拉到其他函数之外,以避免不可避免的事情。

以下是.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 个答案:

答案 0 :(得分:2)

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

您似乎最关心的是方便性,但对于您的代码风格,您发现最方便的并不完全清楚。

如果您想要真正方便,请考虑打开游标并使用cursor.update而不是显式的get和put。虽然游标通常用于迭代多个对象,但使用游标抓取一个对象并不存在任何错误。事实上,这或多或少是get函数在幕后所做的事情。

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

使用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隐式使用相同的事务。这主要是为了方便。