5

Tải dữ liệu và lưu trữ chúng trong cơ sở dữ liệu chỉ mục. Định kỳ tôi có sự cố cơ sở dữ liệu và mất quyền truy cập vào nó. Hãy cho tôi một giải pháp về cách sử dụng indexeddb một cách không đồng bộ!Làm thế nào để làm việc với IndexedDB không đồng bộ?

Mẫu mã mà tôi đang sử dụng hiện nay:

var dataTotal = 0; 
var threads = 6; 

//openIndexeddbConnection(); 

function start(total){ 

dataTotal = total; 
    for (var i = 0; i < threads; i++) { 
    loadData(i); 
    } 
} 

function loadData(dataNum){ 
    var dataNext = dataNum + threads; 
    if(dataNext > dataTotal){ 
    //checkEnd(); 
    return; 
    } 

    $.ajax({ 
    url: baseUrl, 
    data: {offset: dataNum}, 
    success: function (data) { 
     successData(dataNext, data); 
    }, 
    type: 'GET' 
    }); 
} 

function successData(dataNext, data){ 
    var dataArray = data.split(';'); 

    saveData(dataArray); 

    loadData(dataNext); 
} 

function saveData(dataArray){ 

    putItem(); 
    function putItem(i) { 
    var count = i || 0; 
    if(dataArray.length <= i){ 
     return; 
    } 

    var transaction = Indexeddb.transaction([dataTableName], "readwrite"); 
    transaction.onsuccess = function (event) { 
     //continue 
     putItem(count); 
    }; 
    var objectStore = transaction.objectStore(dataTableName); 

    var request = objectStore.add({data: dataArray[count++]}); 
    } 
} 

Trả lời

3

Bạn có thể dùng những lời hứa để tải và lưu dữ liệu không đồng bộ để IndexedDB. Dưới đây là hai hàm ví dụ để tải và lưu dữ liệu vào một đối tượng đơn giản trong indexedDB.

Asynchronous tải từ IndexedDB:

function loadFromIndexedDB(storeName, id){ 
 
    return new Promise(
 
    function(resolve, reject) { 
 
     var dbRequest = indexedDB.open(storeName); 
 

 
     dbRequest.onerror = function(event) { 
 
     reject(Error("Error text")); 
 
     }; 
 

 
     dbRequest.onupgradeneeded = function(event) { 
 
     // Objectstore does not exist. Nothing to load 
 
     event.target.transaction.abort(); 
 
     reject(Error('Not found')); 
 
     }; 
 

 
     dbRequest.onsuccess = function(event) { 
 
     var database  = event.target.result; 
 
     var transaction = database.transaction([storeName]); 
 
     var objectStore = transaction.objectStore(storeName); 
 
     var objectRequest = objectStore.get(id); 
 

 
     objectRequest.onerror = function(event) { 
 
      reject(Error('Error text')); 
 
     }; 
 

 
     objectRequest.onsuccess = function(event) { 
 
      if (objectRequest.result) resolve(objectRequest.result); 
 
      else reject(Error('object not found')); 
 
     }; 
 
     }; 
 
    } 
 
); 
 
}

Asynchronous tiết kiệm để IndexedDB:

function saveToIndexedDB(storeName, object){ 
 
    return new Promise(
 
    function(resolve, reject) { 
 
     if (object.id === undefined) reject(Error('object has no id.')); 
 
     var dbRequest = indexedDB.open(storeName); 
 

 
     dbRequest.onerror = function(event) { 
 
     reject(Error("IndexedDB database error")); 
 
     }; 
 

 
     dbRequest.onupgradeneeded = function(event) { 
 
     var database = event.target.result; 
 
     var objectStore = database.createObjectStore(storeName, {keyPath: "id"}); 
 
     }; 
 

 
     dbRequest.onsuccess = function(event) { 
 
     var database  = event.target.result; 
 
     var transaction = database.transaction([storeName], 'readwrite'); 
 
     var objectStore = transaction.objectStore(storeName); 
 
     var objectRequest = objectStore.put(object); // Overwrite if exists 
 

 
     objectRequest.onerror = function(event) { 
 
      reject(Error('Error text')); 
 
     }; 
 

 
     objectRequest.onsuccess = function(event) { 
 
      resolve('Data saved OK'); 
 
     }; 
 
     }; 
 
    } 
 
); 
 
}

Ví dụ sử dụng đang

var data = {'id' : 1, 'name' : 'bla'}; 
 

 
saveToIndexedDB('objectstoreName', data).then(function (response) { 
 
    alert('data saved'); 
 
}).catch(function (error) { 
 
    alert(error.message); 
 
}); 
 

 
// Load some data 
 
var id = 1; 
 
loadFromIndexedDB('objectstoreName', id).then(function (reponse) { 
 
    data = reponse; 
 
    alert('data loaded OK'); 
 
}).catch(function (error) { 
 
    alert(error.message); 
 
});

+0

Cảm ơn cho câu trả lời. Tôi đã lên kế hoạch trong tương lai để sử dụng Promise sạch, hoặc rxjs. Với lời hứa bắt lỗi thoải mái hơn. Nhưng tôi muốn tạo mã mà không có bất kỳ lỗi nào. Ngoài ra, trong ví dụ bạn mở mỗi lần kết nối indxedDBbut mới, nhưng tôi chỉ sử dụng một kết nối. Tôi nghĩ rằng chúng ta nên sử dụng một cái gì đó như Concurrency Pattern: Nhà sản xuất và người tiêu dùng – Greg

2

Tôi đã sử dụng idb - một thư viện đơn giản kết thúc tốt đẹp IndexedDB với lời hứa. Những hành động này làm cho các hành động DB không đồng bộ nhiều hơn dễ sử dụng hơn.

Nếu bạn đang nhắm mục tiêu Chrome (hoặc đang sử dụng một transpiler hỗ trợ họ), bạn có thể sử dụng asyncawait để đơn giản hóa mã của bạn:

async function saveData(dataArray) { 
    const db = await idb.open('YourDB', currentVersion, upgradeFunction); 
    const tran = await db.transaction('StoreName', 'readwrite'); 
    const store = tran.objectStore('StoreName'); 

    // This will add the items sequentially 
    for(let item of dataArray) { 
     await store.add({data:item}); 
    } 
} 
+0

Cảm ơn câu trả lời của bạn. IDB là một thư viện thú vị, nhưng tôi nghĩ với IndexedDB tôi có thể làm việc mà không cần các trình bao bọc không cần thiết. Ngoài ra vấn đề của thư viện này mà nó không bắt lỗi khi IndexedDB bị chặn. Có, mục tiêu của tôi là chrome, nhưng tôi không muốn sử dụng chờ đợi, mã của tôi cũng hoạt động trong các trình duyệt khác, ngoài ra còn chờ/asynch trong phiên bản beta ngay bây giờ và hoạt động chậm. – Greg

+0

@Greg - async/await là một phần của thông số kỹ thuật sắp tới, chúng không chậm hơn lời hứa vì về cơ bản chúng chỉ thực thi chức năng đó. Với TypeScript, bạn có thể sử dụng chúng và chúng sẽ chuyển thành một thứ gì đó mà IE có thể chạy. Tôi nghĩ rằng bạn có thể với Babel quá, mặc dù tôi đã không thực hiện nó bản thân mình. Tôi không chắc chắn những gì bạn có ý nghĩa về nó không bắt lỗi - đó không phải là những gì nó nghĩa vụ phải làm, tất cả nó làm là bọc chức năng gọi lại với lời hứa. Bạn xử lý lỗi trong mã của riêng bạn với kết quả của lời hứa hoặc bằng cách gói chờ trong một lần thử thường xuyên. – Keith

+0

Có lẽ bạn đang đúng về việc chờ đợi/không đồng bộ, nhưng thường trong các tính năng mới được tạo ra không được tối ưu hóa. Ví dụ: Quảng cáo gốc có tác dụng tồi tệ hơn Polifills. Sự kiện 'bị chặn' được tạo khi một kết nối mở và chúng tôi cố gắng làm nhiều hơn. Và tôi nghĩ rằng sự kiện này được kích hoạt khi xung đột hai giao dịch đồng thời. Và câu hỏi, cách tránh lỗi này. – Greg

Các vấn đề liên quan