5

데이터를로드하고 indexeddb 데이터베이스에 저장합니다. 정기적으로 데이터베이스 충돌이 발생하여 액세스가 끊어졌습니다. indexeddb를 비동기 적으로 사용하는 방법을 알려주세요. 난IndexedDB를 비동기 적으로 사용하는 방법은 무엇입니까?

샘플 코드는 이제 사용 : 당신은 비동기 적으로 색인화 된 데이터를로드하고 저장하는 약속을 사용할 수

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++]}); 
    } 
} 

답변

3

. 다음은 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')); 
 
     }; 
 
     }; 
 
    } 
 
); 
 
}

비동기 색인화에 저장 :

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

사용 예제 코드

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

감사합니다. 나는 미래에 깨끗한 Promise 또는 rxjs를 사용할 계획이었습니다. Promise보다 편안한 catch 오류. 하지만 오류없이 코드를 만들고 싶습니다. 또한이 예제에서는 매번 새로운 indxedDBbut 연결을 열지 만 하나만 사용합니다. 동시성 패턴과 같은 것을 사용해야한다고 생각합니다 : 생산자와 소비자 – Greg

2

나는 IndexedDB을 약자로 묶는 간단한 라이브러리 인 idb을 사용했습니다. 이것들은 비동기 DB 작업을 훨씬 사용하기 쉽게 만듭니다.

당신은 크롬을 타겟팅 (또는 그들을 지원하는 transpiler 사용하는) 당신은 당신의 코드를 단순화하기 위해 asyncawait를 사용할 수있는 경우 : 답변

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

답해 주셔서 감사합니다. IDB는 흥미로운 라이브러리이지만 IndexedDB를 사용하면 불필요한 래퍼없이 작업 할 수 있다고 생각합니다. 또한이 라이브러리의 문제는 IndexedDB가 차단되었을 때 오류를 잡아 내지 못한다는 것입니다. 예, 타겟이 크롬입니다. 그러나 기다리고 싶지 않습니다. 내 코드는 다른 브라우저에서도 작동해야하며, 베타 버전에서 기다리고/asynch하고, 천천히 작동해야합니다. – Greg

+0

@Greg - async/await은 앞으로의 사양의 일부이며 기본적으로 그 기능을 실행하기 때문에 약속보다 느리지는 않습니다. TypeScript를 사용하면 IE를 사용할 수 있으며, IE를 실행할 수 있습니다. 나는 너 혼자 해본 적이 없지만 바벨과도 할 수 있다고 생각한다. 오류에 대한 의미가 무엇인지 잘 모르겠습니다. 즉, 그렇게 할 수있는 것이 아니라 약속으로 랩백 함수를 래핑하는 것입니다. promise의 결과를 가진 자신의 코드에서 오류를 처리하거나 정기적 인 try catch에서 대기를 래핑하여 오류를 처리합니다. – Keith

+0

아마도 대기/비동기에 대해 잘 알고있을 것입니다.하지만 일반적으로 새로운 기능이 처음에는 최적화되지 않았습니다. 예를 들어 네이티브 약속은 Polifills보다 나빴습니다. 하나의 연결이 열리면 '차단됨'이벤트가 생성되고 더 많은 작업을 시도합니다. 그리고이 이벤트는 두 개의 동시 트랜잭션이 충돌 할 때 발생한다고 생각합니다. 질문과 대답,이 오류를 방지하는 방법. – Greg

관련 문제