2012-10-11 12 views
5

Ho diversi UpdatePanels ASP.NET, ciascuno con un AsyncPostBackTrigger legato allo stesso evento click server. Poiché solo un UpdatePanel può fare il suo lavoro alla volta, io uso .get_isInAsyncPostBack() dello PageRequestManager per impedire a un utente di accedere a un'altra parte della pagina fino al completamento del postback async.Javascript: modalità non bloccante per attendere che una condizione sia vera

Un'altra parte di questa pagina deve aggiornare in modo dinamico più pannelli di aggiornamento in modo consecutivo. Poiché i pannelli di aggiornamento utilizzano trigger asincroni, la chiamata __doPostBack("<%=ButtonName.ClientID %>", 'PanelId'); viene attivata in modo asincrono. Per questo motivo, passerà rapidamente alla successiva iterazione del ciclo e tenterà di aggiornare il pannello successivo. Tuttavia, la seconda iterazione fallisce perché c'è già un altro pannello di aggiornamento che fa un postback asincrono.

Idealmente, ci sarebbe un modo per attendere che .get_isInAsyncPostBack() restituisca false senza bloccare altre attività del client.

La ricerca mi ha portato a molte persone con il mio problema, quasi tutti i quali sono invitati a utilizzare setTimeOut(). Non penso che questo funzionerà per me. Non voglio aspettare un intervallo di tempo specificato prima di eseguire una funzione. Voglio semplicemente che il mio Javascript attenda mentre è in esecuzione un altro script, preferibilmente attendere fino a quando una condizione specifica è vera.

Capisco che molti probabilmente vorranno suggerire di ripensare il mio modello. In realtà non è il mio modello, ma quello che è stato consegnato al nostro team di sviluppo che attualmente è un disastro totale sotto il cofano. A causa dei limiti temporali, la riscrittura del modello non è un'opzione. L'unica opzione è far funzionare questo. Penso che se avessi un modo per far aspettare il codice client senza bloccare, il mio problema sarebbe risolto.

+0

Questo semplicemente non è come funziona JavaScript. Eseguirà tutto il codice in modo sincrono. I nuovi HTML5 [Web Workers] (https://developer.mozilla.org/en-US/docs/DOM/Using_web_workers) potrebbero aiutare, ma per il resto non avrai altra scelta che usare 'setTimeout' /' setInterval '. – user2428118

+0

Buona domanda. L'ho trovato quando ne ho provati due ne scrivo uno. – pylover

risposta

26

Non esiste alcuna funzionalità come attesa o sospensione in javascript, poiché impedisce al browser di rispondere.

Nel tuo caso vorrei andare con qualcosa di simile a seguente:

function wait(){ 
    if (!condition){ 
    setTimeout(wait,100); 
    } else { 
    // CODE GOES IN HERE 
    } 
} 
+1

Non sono sicuro di come dovrebbe funzionare. Quando eseguo questo codice 'setTimeout (function() {alert (" waiting ");}, 5000); alert ("donewaiting"); "," donewaiting "viene prima avvisato, seguito da" waiting "5 secondi dopo. A che serve aspettare se si muoverà immediatamente alla prossima riga di codice? – oscilatingcretin

+2

il concetto di timeout impostato è diverso, non interrompe l'esecuzione del codice, ma esegue codice dopo un po 'di tempo. Non c'è modo (almeno buono) di mettere in pausa la sceneggiatura. Dovrai sostituire ... IL CODICE VA IN QUI ... con la logica deve essere eseguito dopo che la condizione è soddisfatta –

+1

Questa tecnica di "polling" esegue essenzialmente la funzione 'wait' ogni 100 ms finché la' condizione' diventa 'true '. Per i tuoi scopi, sostituirò 'condition' qui con' .get_isInAsyncPostBack() 'e' ... CODE GOES IN QUI ... 'con la chiamata per aggiornare il pannello successivo, seguito da un' wait' per il pannello successivo . Avrai bisogno di una nuova funzione 'wait()' per ogni pannello (ad es. 'WaitForPanel1()', 'waitForPanel2()', ecc. –

11

E 'facile fare un errore quando si chiama setTimeout che farà sì che lo stack delle chiamate JavaScript a riempirsi. Se la funzione ha parametri, è necessario passare quelli alla fine della lista setTimeout parametri in questo modo:

function wait(param1, param2){ 
    if (!condition){ 
    setTimeout(wait, 100, param1, param2); 
    } else { 
    // CODE GOES IN HERE 
    } 
} 

Se si passa parametri o anche includere vuota() dopo il nome della funzione, sarà eseguito immediatamente e riempire lo stack.

// This is the wrong way to do it!  
function wait(param1, param2){ 
    if (!condition){ 
    setTimeout(wait(param1, param2), 100); // you'll get max call stack error if you do this! 
    } else { 
    // CODE GOES IN HERE 
    } 
} 
2

Questa funzione chiama condFunc che deve restituire true quando viene soddisfatta la condizione. Quando ciò accade, viene chiamato readyFunc. checkInterval imposta tasso di check-in millisecondi

 var wait = function(condFunc, readyFunc, checkInterval) { 
      var checkFunc = function() { 
       if(condFunc()) { 
        readyFunc(); 
       } 
       else 
       { 
        setTimeout(checkFunc, checkInterval); 
       } 
      }; 
      checkFunc(); 
     }; 

Usage:

 wait(
      function() { return new Date().getSeconds() == 10; }, 
      function() { console.log("Done"); }, 
      100 
     ); 

stampe "Done" quando il tempo attuale è di 10 secondi dopo minuto

0

avevo bisogno di rallentare un processo e si avvicinò con un utile piccolo metodo.

let wait = (seconds) => 
    new Promise(resolve => 
     setTimeout(() => resolve(), seconds * 1000) 
    ); 

E puoi usarlo in questo modo.

(async() => { 
    await wait(3); //wait 3 seconds 
    let result = await doWork(); 
}) 
Problemi correlati