Открытие курсора против использования нескольких запросов get / put в indexedDB? - PullRequest
0 голосов
/ 18 марта 2020

Три записи в одном и том же хранилище объектов необходимо обновить в одной и той же транзакции, и, хотя ключи каждый раз являются переменными и не соответствуют диапазону ключей, который определяет только три, они всегда следуют фиксированному шаблону [0,0,0] а затем [n,0] и [n,m], где n и m - целые числа. Они обеспечивают диапазон в том смысле, что [0,0,0] всегда будет первым, за исключением n = 0, который не используется, и [n,m] всегда будет последним, потому что m всегда больше, чем 0.

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

Спасибо.

Подход 1 - это три get запросов с put запросом в событии onsuccess; один пример ниже.

      req = os.get( [ n, m ] );   // One each for [0,0,0], [n,0], [n,m].
      req.onsuccess = function() 
        {
          let r;
          try
            { 
              if ( req.result )
                {
                  r = req.result;
                  // Update r.
                  os.put( r ); 
                }
              else
                throw 'Record missing from database.';
            } 
          catch( e )
            { /* Handle error. */ }               
          finally
            { r = null; }
        }; // close req.onsuccess

Подход 2 состоит в том, чтобы открыть курсор, продолжая к нужным клавишам, вместо того, чтобы проходить и тестировать каждую из них.

     keys = [ [ 0, 0, 0 ], [ n, 0 ], [ n, m ] ];
     range = IDBKeyRange.bound( [ 0, 0, 0 ], [ n, m ], false, false );
     i = 0;
     os.openCursor( range ).onsuccess = ( e ) =>
       {
         try
           {
             cursor = e.target.result;
             if ( cursor )
               { 
                 v = cursor.value;
                 if ( i === 0 )
                   // Update v.
                 else if ( i === 1 )
                   // Update v.
                 else // i === 2
                   // Update v.
                 cursor.update( v );
                 if ( i < 2 )
                   {
                     i = i + 1;
                     cursor.continue( keys[i] );
                   }; // end if
                }; // end if cursor
             }
           catch( e )
             { /* Handle errors. */ }
        }; // close cursor onsuccess

Я проделал еще кое-что над этим курсор намного медленнее; занимает как минимум вдвое больше времени, хотя для пользователя это не заметно.

Я не знаю, как на самом деле работает get, например, он начинается сверху и ищет вниз. Если так, я ожидал, что три get/put будут медленнее. Я полагаю, что индексирование клавиши ускоряет get, и курсор ищет каждую запись от нижней границы до верхней, даже если в cursor.continue() указана клавиша, и это делает курсор медленнее. Или, возможно, три get/put могут происходить одновременно, и курсор должен завершить каждое отдельное обновление перед выполнением следующего cursor.continue() и выполнением следующего.

Кроме того, я не вижу другого фактора в этом Случай для рассмотрения, кроме скорости. Три оператора get легче кодировать, особенно в отношении обработки ошибок.

У меня есть другая операция, которая может или не может нуждаться в обновлении [0,0,0], но будет обновлять каждую запись с [n,0] до [n,m], а не только конечные точки. Может быть второе обновление одной или нескольких из этих записей в зависимости от действия пользователя, которое его инициировало. Я обрабатывал вторые обновления за пределами курсора, так как они были условными, а затем переместил их в курсор, так как они будут обновлять записи в диапазоне клавиш курсора, когда это необходимо. В то время казалось глупым иметь курсор и затем небольшое количество дополнительных операций get / put для одних и тех же записей. Я не уверен, что быстрее, но может показаться проблематичным c обновить часть записи в курсоре, а затем другую часть в отдельном условном get/put. Я не обнаружил ошибок, когда он был закодирован таким образом, но тестирование было ограничено.

...