В следующем коде
Promise.allSettled( [ entry_save(), save_state(), get_HTML() ] ).then( ... );
обещания entry_save
и save_state
являются readwrite
транзакциями базы данных, а get_HTML
- readonly
. Две readwrite
транзакции могут быть объединены вместе, но это усложняет поддерживаемую цепочку отмены / повтора и связывает успех и откат двух вместе, что нежелательно.
Транзакции entry_save
необходимо записать до транзакции save_state
. Перед перемещением entry_save
в Promise.allSettled
так оно и было, потому что транзакция entry_save
была создана раньше, чем транзакции других. Эта статья MDN объясняет, как порядок, в котором выполняются запросы, основан на том, когда транзакции создаются независимо от порядка, в котором выполняются запросы.
Мой вопрос заключается в том, выполняет ли синхронный код каждого процесса обещания в том порядке, в котором он размещен в массиве, так что размещение entry_save
первым всегда приведет к тому, что его транзакция будет создана первой, а гарантии его запросов к базе данных будут выполнены первыми?
Хотя это работает и достаточно быстро, я бы предпочел не делать этого:
entry_save().then( () => { Promise.allSettled( [ save_state(), get_HTML() ] ) } ).then( ... );
Если это имеет значение, это не совсем то, как написано, это больше соответствует:
entry_save().then( intermediate );
где intermediate
вызывает Promise.allSettled
.
Спасибо.
Для пояснения ниже приведен пример, приведенный в цитированном выше документе MDN.
var trans1 = db.transaction("foo", "readwrite");
var trans2 = db.transaction("foo", "readwrite");
var objectStore2 = trans2.objectStore("foo")
var objectStore1 = trans1.objectStore("foo")
objectStore2.put("2", "key");
objectStore1.put("1", "key");
After the code is executed the object store should contain the value "2", since trans2 should run after trans1.
Если entry_save
создает trans1
и save_state
создает trans2
, и все в синхронном коде функций, то есть не в пределах onsuccess
или onerror
ха После запроса к базе данных или чего-то подобного пример MDN не будет храниться?
Таким образом, где @ jfriend00 пишет,
Функции вызываются в порядке их размещения в массив, но это только определяет порядок, в котором запускаются асинхронные.
будет этот порядок синхронизации запросов на запись по сравнению с созданием транзакций, так как транзакции создаются в синхронном код до того, как может начаться асинхронный?
Я хотел бы проверить его, но я не уверен, как. Если в Promise.allSettled
используются два почти идентичных обещания, как можно отложить запрос на запись первой созданной транзакции, чтобы он выполнялся после запроса на запись второй созданной транзакции, чтобы проверить, будет ли он записан первым? SetTimeout должен завершить транзакцию. Возможно, длительный синхронный l oop, помещенный перед запросом.
Код в самом конце этого вопроса может лучше проиллюстрировать то, что я пытался задать. Он берет пример MDN в приведенной выше статье и распределяет его по двум обещаниям, помещенным в Promise.allSettled
, оба из которых пытаются выполнить запись в одно и то же хранилище объектов из события onsuccess
запроса get
.
Вопрос заключался в том же принципе, что и в статье первой созданной транзакции, написанной до создания второй транзакции, независимо от порядка выполнения запросов, все еще сохраняющегося в этой конфигурации. Поскольку синхронные части обещаний будут обрабатываться в порядке размещения обещаний в массиве, транзакция в обещании p_1
будет создана до операции p_2
. Однако запрос put
в событии onsuccess
запроса get
в p_1
задерживается из-за того, что l oop создает большую строку. Вопрос в том, будет ли p_1
писать еще до p_2
?
Экспериментируя с этим, я не могу заставить p_2
писать до p_1
. Таким образом, кажется, что пример MDN применяется даже в этом типе установки. Однако я не могу быть уверен, почему, потому что я не понимаю, как действительно интерпретируется / обрабатывается код JS.
Например, почему можно определить функцию req.onsuccess
после выполнения запроса? Я задал этот вопрос иногда go, но все еще не знаю достаточно, чтобы быть уверенным, что это не повлияет на то, как я пытался добавить задержку здесь. Я знаю, что это не сработает; но я хочу сказать, что я не уверен, как браузер обрабатывает эту синхронную l oop до того, как запрос put сделан в p_1
, чтобы действительно точно знать, что этот пример демонстрирует, что статья MDN ВСЕГДА выполняется в этой конфигурации. Тем не менее, я могу заметить, что для выполнения запросов требуется больше времени, поскольку увеличивается число итераций l oop; и во всех случаях, которые я наблюдал, p_1
всегда пишет до p_2
. Единственный способ p_2
писать до p_1
- это если p_1
вообще не пишет из-за того, что строка занимает много памяти, что приводит к прерыванию транзакции в p_1
.
сказал, и возвращаясь к более полной постановке моего вопроса относительно трех обещаний в массиве Promise.allSettled
по сравнению с требованием entry_save
завершить до начала Promise.allSettled
на двух оставшихся обещаниях, в полном коде моего проекта по причинам, в которых я не уверен, последнее выполняется быстрее первого, то есть ожидание завершения entry_save
происходит быстрее, чем включение его в Promise.allSettled
.
Я ожидал, что все будет наоборот. Единственная причина, о которой я могу подумать на этом этапе, заключается в том, что, поскольку entry_save
и save_state
записывают в одно и то же хранилище объектов, возможно, что бы браузер ни делал, эквивалентно блокировке хранилища объектов до первой транзакции, то есть entry_save
, для завершения и снятия блокировки требуется больше времени, чем для завершения entry_save
до начала Promise.allSettled
без блокировки. Я думал, что все будет готово "заранее", просто ожидая двух put
запросов в порядке транзакции. Они проходили по порядку, но медленнее или, по крайней мере, не так быстро, как при использовании:
entry_save().then( () => { Promise.allSettled( [ save_state(), get_HTML() ] ) } ).then( ... );
вместо:
Promise.allSettled( [ entry_save(), save_state(), get_HTML() ] ).then( ... );
function p_all() { Promise.allSettled( [ p_1(), p_2() ] ); }
function p_1()
{
return new Promise( ( resolve, reject ) =>
{
let T = DB.transaction( [ 'os_1', 'os_2' ], 'readwrite' ),
q = T.objectStore( 'os_1' ),
u = T.objectStore( 'os_2' ),
req, i, t ='', x = '';
req = q.get( 1 );
req.onsuccess = () =>
{
let i, t, r = req.result;
for ( i = 1; i < 10000000; i++ ) t = t + 'This is a string';
r.n = 'p1';
u.put( r );
console.log( r );
};
}); }
function p_2()
{
return new Promise( ( resolve, reject ) =>
{
let T = DB.transaction( [ 'os_1', 'os_2' ], 'readwrite' ),
q = T.objectStore( 'os_1' ),
u = T.objectStore( 'os_2' ),
req;
req = q.get( 1 );
req.onsuccess = () =>
{
let r = req.result;
r.n = 'p2';
u.put( r );
console.log( r );
};
}); }