2017-03-07 4 views
10

IndexedDB transactions commit across tasks, but not microtasks은 태스크와 마이크로 태스크의 구분이 중요합니다. 이는 Firefox (및 다른 브라우저)에서 약속 해상도가 마이크로 태스크에서 발생하지 않기 때문에 Promise에서 IndexedDB 코드를 래핑 할 때 문제가되므로 트랜잭션이 커밋됩니다.웹 작업자 내부의 마이크로 태스크

이 문제에 대한 해결책은 마이크로 태스크를 사용하는 타사 약속 구현을 사용하는 것입니다. lie은 그러한 라이브러리 중 하나이며 마이크로 후드 문제는 immediate이라는 다른 라이브러리로 추상화합니다.이 라이브러리는 MutationObserver을 사용하여 마이크로 태스크를 생성합니다.

대단히 효과적입니다. 그러나 웹 작업자의 경우 MutationObserver은 존재하지 않으므로 트릭이 작동하지 않습니다. Here's an example of the problem in an easily-runnable GitHub repo. 기본적으로이 코드가 있습니다 :

var immediate = require('immediate'); 

var openRequest = indexedDB.open('firefox-indexeddb-promise-worker-test'); 

openRequest.onupgradeneeded = function() { 
    var db = openRequest.result; 
    var store = db.createObjectStore('whatever', {keyPath: 'id'}); 

    store.put({id: 1}); 
    store.put({id: 2}); 
    store.put({id: 3}); 
}; 

function get(tx, id, cb) { 
    immediate(function() { 
     var req = tx.objectStore('whatever').get(id); 
     req.onsuccess = function (e) { 
      console.log('got', e.target.result); 
      if (cb) { 
       cb(null, e.target.result); 
      } 
     }; 
     req.onerror = function (e) { 
      console.error(e.target.error); 
      if (cb) { 
       cb(e.target.error); 
      } 
     }; 
    }); 
} 

openRequest.onsuccess = function() { 
    var db = openRequest.result; 

    var tx = db.transaction('whatever'); 
    tx.oncomplete = function() { 
     console.log('tx complete'); 
    }; 

    get(tx, 1, function() { 
     get(tx, 2); 
    }); 
}; 

정상적으로 실행하면 정상적으로 작동합니다. 웹 작업자에서 실행하면 콜백이 실행되기 전에 immediate이 호출 될 때 트랜잭션이 커밋되기 때문에 실패합니다. 이 문제는 Chrome과 Firefox에서 발생합니다.

는 지금, 나는이 개 솔루션을 생각했습니다

  1. 동기 해상도

그 모두 지옥에게

  • 사용 약속을 콜백으로 돌아가, 약속을 사용하지 마십시오 옵션은 매우 unsatifying 있습니다. 스택 오버플로, 웹 작업자 내부에 마이크로 작업 대기열을 만드는 방법을 알고 있습니까?

  • +0

    리졸버 내에서 콜백을 동기 실행하는 약속은 소리가 나쁘지 않습니다. a) 해상도 자체가 비동기 적으로 (또는 최소한 턴이 끝날 때) 트리거되고 b) 해결을 트리거하는 당사자를 신뢰할 수 있는지 확인해야합니다. – Bergi

    +0

    "매크로 태스크"에 대한 질문의 시작 문장, 그러나 그 후에 "microtasks". 이것은 의도적입니까? 그렇다면 설명해주십시오. –

    +0

    @Bergi는 당신이 설명하는대로 행동하는 라이브러리에 대해 알고 있습니까? – dumbmatter

    답변

    5

    짧은 대답 : 당신은 웹 노동자에

    긴 대답을 할 수 없어 : 실제 microtask API는 없다, 단지 그들을 시뮬레이션하려고 해킹있다. 불행히도 가장 잘 작동하는 것 (돌연변이 관찰자)은 주로 DOM과 관련이 있으므로 웹 작업자가 아닌 메인 스레드에서만 사용할 수 있습니다. 그것이 IDB와 공식적인 관계를 표준화하겠다는 약속을하는 것이 맞을지 모른다고 말하면서 실제로 약속과 IDB가 다른 그룹에서 나온 것인지 확실하지 않습니다. 대부분의 이의 제기가 우연히 메인 스레드를 다루는 것과 관련이 있기 때문에 실제로 웹 작업자 내부에 실제 마이크로 태스크 API를 수행하는 것에 대한 브라우저 공급 업체의 견인력이있을 수 있습니다.

    +0

    https://github.com/inexorabletash/indexeddb-promises/ IDB와 약속을 표준화하려는 노력이 있지만 거기에는 많은 견인력이있는 것 같지 않습니다. (저는 브라우저 개발자가 아니므로 잘하면 틀렸습니다. 그것에 대해). – dumbmatter