[ Web Proxy ]
URL:
Viewing: https://it.javascript.info/microtask-queue [Back]  [Original]

Microtasks
IT

Vorremo rendere disponibile questo progetto open-source per persone in tutto il mondo.

Aiutaci a tradurre il contenuto di questo tutorial nella tua lingua!

    Cerca in Javascript.info:
    Cerca nel tutorial:
    Light themeDark theme
    DanskEnglishEspaolFranaisIndonesiaItalianoTrkeOzbek

    I gestori delle Promise .then/.catch/.finally sono sempre asincroni.

    Anche quando una Promise immediatamente risolta, il codice sulle linee sotto .then/.catch/.finally verr sempre eseguito prima dei gestori.

    Ecco una dimostrazione:

    let promise = Promise.resolve();
    
    promise.then(() => alert("promise completa"));
    
    alert("codice finito"); // questo alert viene mostrato prima

    Se lo esegui, vedrai prima codice finito, in seguito promise done.

    Questo strano, perch la Promise chiaramente completa dallinizio.

    Perch quindi il .then viene eseguito dopo? Cosa succede?

    Coda dei Microtask (Microtasks Queue)

    I task asincroni hanno bisogno di una gestione appropriata. Per questo motivo, lo standard specifica una coda interna PromiseJobs, pi spesso riferita come coda dei microtask (microtask queue) (termine di v8).

    Come detto nella specifica:

    • La coda primo-dentro-primo-fuori: i task messi in coda per primi sono eseguiti per primi.
    • Lesecuzione di un task iniziata solo quando nientaltro in esecuzione.

    Oppure, per dirla in modo semplice, quando una promise pronta, i suoi gestori .then/catch/finally sono messi nella coda. Non vengono ancora eseguiti. Il motore JavaScript prende un task dalla coda e lo esegue, quando diventa libero dal codice corrente.

    Questo il motivo per cui codice finito nellesempio sopra viene mostrato prima.

    []

    I gestori delle promise passano sempre da quella coda interna.

    Se c una catena con diversi .then/catch/finally, allora ognuno di essi viene eseguito in modo asincrono. Cio, viene prima messo in coda ed eseguito quando il codice corrente completo e i gestori messi in coda precedentemente sono finiti.

    Che cosa succede se per noi lordine importante? Come possiamo far funzionare code finished dopo promise done?

    Facile, basta metterlo in coda con .then:

    Promise.resolve()
      .then(() => alert("promise done!"))
      .then(() => alert("code finished"));

    Ora lordine come inteso.

    Rigetto non gestito (Unhandled rejection)

    Ricordi levento unhandledrejection dal capitolo Gestione degli errori con le promise?

    Ora possiamo vedere esattamente come JavaScript viene a conoscenza che c stato un respingimento non gestito (unhandled rejection)

    Unhandled rejection avviene quando un errore di una promise non gestito alla fine della coda dei microtask

    Normalmente, se ci aspettiamo un errore, aggiungiamo .catch alla catena delle promise per gestirlo:

    let promise = Promise.reject(new Error("Promise Fallita!"));
    promise.catch(err => alert('catturato'));
    
    // non viene eseguito: errore gestito
    window.addEventListener('unhandledrejection', event => alert(event.reason));

    Ma se ci dimentichiamo di aggiungere .catch, allora, dopo che la coda dei microtask vuota, il motore innesca levento:

    let promise = Promise.reject(new Error("Promise Fallita!"));
    
    // Promise Fallita!
    window.addEventListener('unhandledrejection', event => alert(event.reason));

    Cosa succede se gestiamo lerrore dopo? Come qui:

    let promise = Promise.reject(new Error("Promise Fallita!"));
    setTimeout(() => promise.catch(err => alert('caught')), 1000);
    
    // Error: Promise Fallita!
    window.addEventListener('unhandledrejection', event => alert(event.reason));

    Ora il respingimento non gestito appare di nuovo. Perch? unhandledrejection viene innescato quando la coda dei microtask completa. Il motore esamina le promise e, se qualcuna di esse in stato rejected, allora levento generato.

    Nellesempio, il .catch aggiunto da setTimeout viene es, ovviamente lo fa, ma dopo, quando unhandledrejection gi avvenuto.

    Se non fossimo a conoscenza della coda dei microtask, potremmo chiederci: Perch il gestore di unhandledrejection viene eseguito? Abbiamo catturato lerrore!.

    Ma ora sappiamo che unhandledrejection generato quando la coda dei microtask completa: il motore esamina le promise e, se una di esse in stato rejected, allora levento viene innescato.

    Nellesempio sopra, anche il .catch aggiunto da setTimeout viene innescato, ma dopo, quando unhandledrejection gi avvenuto, quindi questo non cambia niente.

    Riepilogo

    La gestione delle promise sempre asincrona, dato che tutte le azioni delle promise passano attraverso la coda promise jobs, anche chiamata microtask queue (termine di v8).

    Cos, i gestori .then/catch/finally sono sempre chiamati dopo che il codice corrente finito.

    Se abbiamo bisogno della certezza che un pezzo di codice sia eseguito dopo .then/catch/finally, possiamo aggiungerlo ad una chiamata .then in catena.

    Nella maggior parte dei motori JavaScript, inclusi i browser e Node.js, il concetto di microtask strettamente legato al loop degli event (event loop) ed ai macrotasks. Dato che questi non hanno una relazione diretta con le promise, sono coperti in unaltra parte del tutorial, nel capitolo Event loop: microtasks e macrotasks.

    Mappa del tutorial

    Commenti

    leggi questo prima di lasciare un commento
    • Per qualsiasi suggerimento - per favore, apri una issue su GitHub o una pull request, piuttosto di lasciare un commento.
    • Se non riesci a comprendere quanto scitto nell'articolo ti preghiamo di fornire una spiegazione chiara.
    • Per inserire delle righe di codice utilizza il tag <code>, per molte righe includile nel tag <pre>, per pi di 10 righe utilizza una sandbox (plnkr, jsbin, codepen)

    Web Proxy Viewer  |  New URL  |  Original Page