Saat menggunakan callback sederhana seperti pada contoh di bawah ini:
test() {
api.on( 'someEvent', function( response ) {
return response;
});
}
Bagaimana fungsi diubah untuk menggunakan async / await? Secara khusus, dengan asumsi 'someEvent' dijamin akan dipanggil sekali dan hanya sekali, saya ingin pengujian fungsi menjadi fungsi asinkron yang tidak kembali sampai callback dijalankan seperti:
async test() {
return await api.on( 'someEvent' );
}
Jawaban:
async/await
bukan sihir. Fungsi asinkron adalah fungsi yang dapat membuka bungkusan Promises untuk Anda, jadi Anda memerlukannyaapi.on()
mengembalikan Promise agar dapat berfungsi. Sesuatu seperti ini:function apiOn(event) { return new Promise(resolve => { api.on(event, response => resolve(response)); }); }
Kemudian
async function test() { return await apiOn( 'someEvent' ); // await is actually optional here // you'd return a Promise either way. }
Tapi itu juga bohong, karena fungsi async juga mengembalikan Promises sendiri, jadi Anda tidak akan benar-benar mendapatkan nilainya
test()
, melainkan Promise untuk sebuah nilai, yang dapat Anda gunakan seperti ini:async function whatever() { // snip const response = await test(); // use response here // snip }
sumber
const apiOn = (event) => new Promise(resolve => api.on(event, resolve));
Sangat menjengkelkan bahwa tidak ada solusi yang langsung, dan pembungkusan
return new Promise(...)
sangat buruk, tetapi saya telah menemukan solusi yang baik untuk digunakanutil.promisify
(sebenarnya itu juga melakukan pembungkusan yang sama, hanya terlihat lebih bagus).function voidFunction(someArgs, callback) { api.onActionwhichTakesTime(someMoreArgs, (response_we_need) => { callback(null, response_we_need); }); }
Fungsi di atas belum mengembalikan apa pun. Kita bisa membuatnya mengembalikan
Promise
dariresponse
berlalu dalamcallback
dengan melakukan:const util = require('util'); const asyncFunction = util.promisify(voidFunction);
Sekarang kita dapat benar-benar
await
yangcallback
.async function test() { return await asyncFunction(args); }
Beberapa aturan saat menggunakan
util.promisify
callback
harus argumen terakhir dari fungsi yang akan menjadipromisify
(err, res) => {...}
Lucunya, kita tidak perlu pernah secara spesifik menulis apa yang
callback
sebenarnya.sumber
async / await adalah keajaiban. Anda dapat membuat fungsi
asPromise
untuk menangani situasi seperti ini:function asPromise(context, callbackFunction, ...args) { return new Promise((resolve, reject) => { args.push((err, data) => { if (err) { reject(err); } else { resolve(data); } }); if (context) { callbackFunction.call(context, ...args); } else { callbackFunction(...args); } }); }
lalu gunakan saat Anda ingin:
async test() { return await this.asPromise(this, api.on, 'someEvent'); }
jumlah arg adalah variabel.
sumber
Anda dapat mencapai ini tanpa callback, gunakan promise async await daripada callback di sini, seperti yang saya lakukan. Dan juga di sini saya telah mengilustrasikan dua metode untuk menangani kesalahan
clickMe = async (value) => { // begin to wait till the message gets here; let {message, error} = await getMessage(value); // if error is not null if(error) return console.log('error occured ' + error); return console.log('message ' + message); } getMessage = (value) => { //returning a promise return new Promise((resolve, reject) => { setTimeout(() => { // if passed value is 1 then it is a success if(value == 1){ resolve({message: "**success**", error: null}); }else if (value == 2){ resolve({message: null, error: "**error**"}); } }, 1000); }); } clickWithTryCatch = async (value) => { try{ //since promise reject in getMessage2 let message = await getMessage2(value); console.log('message is ' + message); }catch(e){ //catching rejects from the promise console.log('error captured ' + e); } } getMessage2 = (value) => { return new Promise((resolve, reject) => { setTimeout(() => { if(value == 1) resolve('**success**'); else if(value == 2) reject('**error**'); }, 1000); }); }
<input type='button' value='click to trigger for a value' onclick='clickMe(1)' /> <br/> <input type='button' value='click to trigger an error' onclick='clickMe(2)' /> <br/> <input type='button' value='handling errors with try catch' onclick='clickWithTryCatch(1)'/> <br/> <input type='button' value='handling errors with try catch' onclick='clickWithTryCatch(2)'/>
sumber