javascript - Kako odbiti u async/await sintaksi?


Kako mogu odbiti obećanje koje vraća async/await funkcija?

npr. Izvorno:

foo(id: string): Promise<A> {
  return new Promise((resolve, reject) => {
    someAsyncPromise().then((value)=>resolve(200)).catch((err)=>reject(400))
  });
}

Prevedi u async/await:

async foo(id: string): Promise<A> {
  try{
    await someAsyncPromise();
    return 200;
  } catch(error) {//here goes if someAsyncPromise() rejected}
    return 400; //this will result in a resolved promise.
  });
}

Pa, kako bih u ovom slučaju mogao ispravno odbiti ovo obećanje?

Odgovor #1

Vaša najbolja opcija je throw Error koji obavija vrijednost, što rezultira odbijenim obećanjem s Error koji obavija vrijednost:

} catch (error) {
    throw new Error(400);
}

Također možete jednostavno baci vrijednost, ali tada nema informacija o tragovima stoga:

} catch (error) {
    throw 400;
}

Alternativno, vrati odbijeno obećanje s Error koji obavija vrijednost, ali to nije idiomatično:

} catch (error) {
    return Promise.reject(new Error(400));
}

(Ili jednostavno return Promise.reject(400);, ali opet, tada nema informacija o kontekstu.)

U vašem slučaju, budući da koristite TypeScript i da je povratna vrijednost foo Promise<A>, koristili biste ovo:

return Promise.reject<A>(400 /*or Error*/ );

U async/await situaciji, posljednje je vjerojatno malo semantički nepodudaranje, ali ipak funkcionira.

Ako baciš Error, to dobro funkcionira sa svime što konzumira rezultat tvog foo pomoću await sintakse:

try {
    await foo();
} catch (error) {
    // Here, `error` would be an `Error` (with stack trace, etc.).
    // Whereas if you used `throw 400`, it would just be `400`.
}

Odgovor #2

Vjerojatno bi također trebalo spomenuti da možete jednostavno povezati funkciju catch() nakon poziva vaše asinhrone operacije jer se u pozadini i dalje vraća obećanje.

await foo().catch(error => console.log(error));

Na ovaj način možete izbjeći try/catch sintaksu ako vam se ne sviđa.

Odgovor #3

Možete kreirati omotnu funkciju koja prima obećanje i vraća niz s podacima ako nema pogreške i pogrešku ako je došlo do pogreške.

function safePromise(promise) {
  return promise.then(data => [ data ]).catch(error => [ null, error ]);
}

Koristite ga ovako u ES7 i u async funkciji:

async function checkItem() {
  const [ item, error ] = await safePromise(getItem(id));
  if (error) { return null; } // handle error and return
  return item; // no error so safe to use item
}

Odgovor #4

Bolji način pisanja asinhrone funkcije bio bi vraćanje obećanja (Promise) u stanju čekanja od samog početka, a zatim rukovanje i odbijanjem i ispunjenjem unutar callback funkcije obećanja, umjesto da se samo baci odbijeno obećanje u slučaju pogreške. Primjer:

async foo(id: string): Promise<A> {
    return new Promise(function(resolve, reject) {
        // execute some code here
        if (success) { // let's say this is a boolean value from line above
            return resolve(success);
        } else {
            return reject(error); // this can be anything, preferably an Error object to catch the stacktrace from this function
        }
    });
}

Zatim samo povežete metode na vraćeni obećanje:

async function bar () {
    try {
        var result = await foo("someID")
        // use the result here
    } catch (error) {
        // handle error here
    }
}

bar()

Izvor - ovaj vodič:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise

Povezani članci