Perché le promesse non sono "attese" di default?

1

Nell'ultima versione di lingue come TypeScript o ECMAScript puoi usare async / await costrutti per scrivere codice che combina la struttura pulita della programmazione sincrona con i vantaggi prestazionali del codice asincrono.

Prendi questo come esempio:

async function isAdmin() {
    // Async IO request...
    return false;
}

async function doSomething() {
    if (await isAdmin()) {
        console.log("Done");
    } else throw new Error("Unauthorized");
}

doSomething();

Sembra molto pulito. Tuttavia, a causa dell'aspetto sincrono del codice, non è difficile dimenticare await su qualche invocazione di funzione, scrivendo cose del genere:

// ...
if (isAdmin()) {
    console.log("Done");
} else throw new Error("Unauthorized");

che è pericolosamente sbagliato.

Qual è la logica alla base di questa scelta, invece di attendere tutte le funzioni asincrone di default e lasciare che il programmatore scelga l'operazione in modo asincrono? Qualcosa come questa sintassi inventata:

var admin = isAdmin(); // wait isAdmin to return a result
async doSomething();   // call doSomething asynchronously
doSomething();         // call doSomething synchronously
var promise = async doSomething(); // Get the underlying Promise
    
posta danieleds 10.08.2016 - 17:23
fonte

2 risposte

2

Si noti che una funzione che è async non la trasforma in qualcosa di completamente diverso, ma solo abilita una certa sintassi. Una funzione normale che restituisce una promessa è asincrona quanto una funzione contrassegnata con async .

  1. Il await serve come un segnale di avvertimento "il mondo potrebbe essere cambiato nel frattempo".

    await potrebbe essere più facile rispetto al multi-threading, ma è ancora molto soggetto a errori. Durante la revisione del codice devi esaminare ogni await , pensando "la funzione si basa su qualsiasi informazione ottenuta prima che await sia ancora la stessa? È garantito?". Senza un esplicito await , devi farlo ad ogni richiamo di funzione.

  2. Compatibilità con le versioni precedenti. Con il tuo codice proposta si comporta in modo completamente diverso se browse / runtime supporta l'attesa o meno.
  3. Se il tuo codice non vuole essere in attesa, deve inserire un async ad ogni chiamata a una funzione definita esternamente, nel caso in cui restituisca una promessa.
  4. Prestazioni. Il runtime deve inserire un controllo if result is a promise then await ad ogni chiamata di metodo.
risposta data 10.08.2016 - 17:53
fonte
1

Perché potresti non voler attendere tutte le tue funzioni. Potresti volere che alcune di queste funzioni in modo sincrono.

Il tuo esempio non è "pericolosamente sbagliato", è semplicemente sincrono.

A proposito, non dovresti avere await una funzione chiamata isAdmin() ; dovrebbe tornare quasi immediatamente comunque, e poiché l'istruzione if ha bisogno del risultato di ritorno prima che possa procedere, probabilmente non verrà nemmeno eseguita in modo asincrono.

Sul motivo per cui vengono utilizzate due parole chiave anziché una, è spiegato nella Proposta TypeScript per le funzioni asincrone :

An Async Function is a JavaScript Function, Parameterized Arrow Function, Method, or Get Accessor that has been prefixed with the async modifier. This modifier informs the compiler that function body transposition is required, and that the keyword await should be treated as a unary expression instead of an identifier.

    
risposta data 10.08.2016 - 17:33
fonte