Javascript 控制清理函数相对于indexedDB中异步请求的执行顺序?
在indexedDB数据库事务中,有多个Javascript 控制清理函数相对于indexedDB中异步请求的执行顺序?,javascript,asynchronous,settimeout,indexeddb,Javascript,Asynchronous,Settimeout,Indexeddb,在indexedDB数据库事务中,有多个add、get和put请求位于try catch中。即使用户在外部篡改数据,在试图保护程序不失败时也会出现一个问题,即当其中一个请求出错时,所有请求的错误事件都会被触发并冒泡到事务错误事件,因此transaction.onerror中的代码会多次运行。通过将布尔变量声明为false,然后在transaction.onerror中将其设置为true,并在每个请求.onerror函数中对其进行测试,如果为true,则执行evt.stopPropagation(
add
、get
和put
请求位于try catch
中。即使用户在外部篡改数据,在试图保护程序不失败时也会出现一个问题,即当其中一个请求出错时,所有请求的错误事件都会被触发并冒泡到事务错误事件,因此transaction.onerror
中的代码会多次运行。通过将布尔变量声明为false,然后在transaction.onerror
中将其设置为true,并在每个请求.onerror
函数中对其进行测试,如果为true,则执行evt.stopPropagation()
除了一个小问题外,这是可行的。为了防止内存泄漏的可能性,在transaction.oncomplete
和transaction.onerror
结束时,通过调用内部函数freeRAM(),将数据库函数中的所有变量设置为null。由于transaction.onerror
函数可以在发出所有请求之前执行,因此freeRAM()函数可以将所有变量设置为null,从而导致其他本可以成功运行的请求失败,并且由于布尔变量也被清除,用于阻止后续请求错误冒泡到transaction.onerror
的技术失败,因为该变量在该点为null
我的问题是,有没有一种方法可以在所有请求成功或出错后执行freeRAM()?freeRAM()上的setTimeout
是否能确保在所有请求完成后它进入堆栈
在测试中,在执行freeRAM()之前,在transaction.onerror
函数中放置一条提示数据库错误的警报消息,让请求有时间完成;但是我想要一个更好的方法。我知道我不能简单地将“error”和其他相关变量设置为null,但我想知道是否可以将freeRAM()的执行设置为始终在所有请求完成后执行
我尝试使用setTimeout(free_RAM,0)
代替alert
,它似乎可以工作,但我不确定它是否会在请求完成后始终执行freeRAM(),或者它是否只是用于我的测试。也许,在用户单击“确定”后执行freeRAM()的自定义消息就足够了,或者可以为setTimeout
添加更多时间。这些是短事务,请求写入少量数据
代码如下。多谢各位
error = false;
T.onerror = ( v ) =>
{
v.stopPropagation(); // Stop propagation up to the database error level in the database open block.
if ( !error )
{
error = true;
// Next two statements must execute only once.
if ( m ) { Q.max = key - 1; } else { Q.gap.push(key); };
if ( log ) undo_rollbackKey( qst_undo );
alert( 'bad data' ); // If this is removed, program fails for bad data.
free_RAM(); // Sets all variables, including 'error' to null;
}; // end if
v = null;
}; // close T.onerror
// Within the try-catch is code like this, involving 'error'.
for ( i = 0; i < 9; i++ )
{
req_a = q.add( { 'k' : k[i], 'c' : d, 'e' : d, 'E' : [] } );
req_a.onerror = ( evt ) => { if ( error ) evt.stopPropagation(); };
}; // next i
req_b = q.add( { 'k' : [ key, 3, 0 ], 'g' : [], 'm' : 0, 'q' : [], 'N' : '', 'P' : '' } );
req_b.onerror = ( evt ) => { if ( error ) evt.stopPropagation(); };
let Q = { /* Object data */ },
error = false;
function freeRAM() { Q = error = null; }
T.onerror = ( v ) => { v.stopPropagation(); };
T.onabort = ( v ) =>
{
v.stopPropagation();
if ( !error )
{
error = true;
// Next two statements must execute only once.
if ( m ) { Q.max = key - 1; } else { Q.gap.push(key); };
if ( log ) undo_rollbackKey( qst_undo );
free_RAM(); // Sets all variables, including 'error' to null;
}; // end if
v = null;
}; // close T.onerror
try {
for ( i = 0; i < 9; i++ )
{ q.add( { 'k' : k[i], 'c' : d, 'e' : d, 'E' : [] } ); };
req = q.get( [ 0, 0, 0 ] );
req.onsuccess = function()
{
let r;
try {
if ( req.result )
{
r = req.result;
/* Update r using variable set to null by freeRAM() */
r.m = Q.max;
q.put( r );
}; // end if
}
catch(e) { if ( !error ) T.abort(); }
finally { r = null; }
}; // close req.onsuccess
} // close try
catch { if ( !error ) T.abort(); }