Несовместимое взаимодействие между транзакциями IndexedDB и Обещаниями

Я виделсинхронизации обещание размещены на Reddit ивступил в дискуссию с автором, Мы заметили некоторые странные несоответствия в отношениях между транзакциями и обещаниями IndexedDB.

Транзакции IndexedDB автоматически фиксируются, когда всеonsuccess События заканчиваются. Одним из осложнений является то, что вы не можете делать ничего асинхронного внутриonsuccess обратный вызов, кроме как сделать другую операцию с той же транзакцией. Например, вы не можете запустить AJAX-запрос вonsuccess и затем повторно использовать ту же транзакцию после того, как AJAX-запрос вернет некоторые данные.

При чем тут обещания? Насколько я понимаю, разрешение обещаний всегда должно быть асинхронным. Это будет означать, что вы не можете использовать обещания без автоматической фиксации транзакции IndexedDB.

Вот пример того, о чем я говорю:

var openRequest = indexedDB.open("library");

openRequest.onupgradeneeded = function() {
  // The database did not previously exist, so create object stores and indexes.
  var db = openRequest.result;
  var store = db.createObjectStore("books", {keyPath: "isbn"});
  var titleIndex = store.createIndex("by_title", "title", {unique: true});
  var authorIndex = store.createIndex("by_author", "author");

  // Populate with initial data.
  store.put({title: "Quarry Memories", author: "Fred", isbn: 123456});
  store.put({title: "Water Buffaloes", author: "Fred", isbn: 234567});
  store.put({title: "Bedrock Nights", author: "Barney", isbn: 345678});
};

function getByTitle(tx, title) {
  return new Promise(function(resolve, reject) {
    var store = tx.objectStore("books");
    var index = store.index("by_title");
    var request = index.get("Bedrock Nights");
    request.onsuccess = function() {
      var matching = request.result;
      if (matching !== undefined) {
        // A match was found.
        resolve(matching);
      } else {
        // No match was found.
        console.log('no match found');
      }
    };
  });
}

openRequest.onsuccess = function() {
  var db = openRequest.result;
  var tx = db.transaction("books", "readonly");
  getByTitle(tx, "Bedrock Nights").then(function(book) {
    console.log('First book', book.isbn, book.title, book.author);
    return getByTitle(tx, "Quarry Memories");
  }).then(function(book) {
    console.log('Second book', book.isbn, book.title, book.author);
    // With native promises this gives the error:
    // InvalidStateError: An attempt was made to use an object that is not, or is no longer, usable
    // With bluebird everything is fine
  });
};

(Полное раскрытие: демо было создано Палдепиндом, а не мной!)

Я пробовал это в Chrome и Firefox. В Firefox происходит сбой из-за автоматической фиксации транзакции, но на самом деле он работает в Chrome! Какое поведение правильно? И если поведение Firefox правильное, то буквально невозможно использовать «правильные» реализации обещаний с транзакциями IndexedDB?

Еще одно осложнение: если я загружупевчая птица перед запуском вышеприведенной демонстрации он работает как в Chrome, так и в Firefox. Означает ли это, что синяя птица выполняет обещания синхронно? Я думал, что это не должно было делать это!

JSFiddle

Ответы на вопрос(0)

Ваш ответ на вопрос