Fungsi Async , fitur di ES2017 , membuat sinkronisasi kode async dengan menggunakan janji (bentuk tertentu dari kode async) dan await
kata kunci. Perhatikan juga dalam contoh kode di bawah kata kunci async
di depan function
kata kunci yang menandakan fungsi async / menunggu. Kata await
kunci tidak akan berfungsi tanpa berada dalam fungsi yang telah diperbaiki sebelumnya dengan async
kata kunci. Karena saat ini tidak ada pengecualian untuk ini yang berarti tidak ada level atas yang menunggu akan berfungsi (level atas menunggu artinya menunggu di luar fungsi apa pun). Padahal ada proposal untuk level atasawait
.
ES2017 telah disahkan (yaitu difinalisasi) sebagai standar untuk JavaScript pada 27 Juni 2017. Async menunggu mungkin sudah berfungsi di browser Anda, tetapi jika tidak Anda masih dapat menggunakan fungsionalitas menggunakan javascript transpiler seperti babel atau traceur . Chrome 55 mendapat dukungan penuh dari fungsi-fungsi async. Jadi, jika Anda memiliki peramban yang lebih baru, Anda mungkin dapat mencoba kode di bawah ini.
Lihat tabel kompatibilitas es2017 kangax untuk kompatibilitas peramban.
Berikut ini contoh fungsi menunggu async doAsync
yang dipanggil yang mengambil tiga satu jeda detik dan mencetak perbedaan waktu setelah setiap jeda dari waktu mulai:
function timeoutPromise (time) {
return new Promise(function (resolve) {
setTimeout(function () {
resolve(Date.now());
}, time)
})
}
function doSomethingAsync () {
return timeoutPromise(1000);
}
async function doAsync () {
var start = Date.now(), time;
console.log(0);
time = await doSomethingAsync();
console.log(time - start);
time = await doSomethingAsync();
console.log(time - start);
time = await doSomethingAsync();
console.log(time - start);
}
doAsync();
Ketika kata kunci yang menunggu ditempatkan sebelum nilai janji (dalam hal ini nilai janji adalah nilai yang dikembalikan oleh fungsi doSomethingAsync) kata kunci yang menunggu akan menjeda pelaksanaan panggilan fungsi, tetapi tidak akan menghentikan sementara fungsi lain dan itu akan melanjutkan mengeksekusi kode lain sampai janji terselesaikan. Setelah janji terselesaikan, itu akan membuka nilai janji dan Anda dapat memikirkan ekspresi menunggu dan janji yang sekarang sedang digantikan oleh nilai yang terbuka.
Jadi, karena menunggu hanya jeda menunggu kemudian membuka nilai sebelum mengeksekusi sisa baris Anda dapat menggunakannya dalam untuk loop dan panggilan fungsi di dalam seperti dalam contoh di bawah ini yang mengumpulkan perbedaan waktu yang ditunggu dalam array dan mencetak array.
function timeoutPromise (time) {
return new Promise(function (resolve) {
setTimeout(function () {
resolve(Date.now());
}, time)
})
}
function doSomethingAsync () {
return timeoutPromise(1000);
}
// this calls each promise returning function one after the other
async function doAsync () {
var response = [];
var start = Date.now();
// each index is a promise returning function
var promiseFuncs= [doSomethingAsync, doSomethingAsync, doSomethingAsync];
for(var i = 0; i < promiseFuncs.length; ++i) {
var promiseFunc = promiseFuncs[i];
response.push(await promiseFunc() - start);
console.log(response);
}
// do something with response which is an array of values that were from resolved promises.
return response
}
doAsync().then(function (response) {
console.log(response)
})
Fungsi async sendiri mengembalikan janji sehingga Anda dapat menggunakannya sebagai janji dengan rantai seperti yang saya lakukan di atas atau di dalam fungsi menunggu async lainnya.
Fungsi di atas akan menunggu setiap respons sebelum mengirim permintaan lain jika Anda ingin mengirim permintaan secara bersamaan, Anda dapat menggunakan Promise.all .
// no change
function timeoutPromise (time) {
return new Promise(function (resolve) {
setTimeout(function () {
resolve(Date.now());
}, time)
})
}
// no change
function doSomethingAsync () {
return timeoutPromise(1000);
}
// this function calls the async promise returning functions all at around the same time
async function doAsync () {
var start = Date.now();
// we are now using promise all to await all promises to settle
var responses = await Promise.all([doSomethingAsync(), doSomethingAsync(), doSomethingAsync()]);
return responses.map(x=>x-start);
}
// no change
doAsync().then(function (response) {
console.log(response)
})
Jika janji itu mungkin ditolak, Anda dapat membungkusnya dengan try catch atau melewati try catch dan membiarkan kesalahan tersebut menyebar ke fungsi async / await catch call. Anda harus berhati-hati untuk tidak meninggalkan kesalahan janji tidak tertangani terutama di Node.js. Di bawah ini adalah beberapa contoh yang menunjukkan bagaimana kesalahan bekerja.
function timeoutReject (time) {
return new Promise(function (resolve, reject) {
setTimeout(function () {
reject(new Error("OOPS well you got an error at TIMESTAMP: " + Date.now()));
}, time)
})
}
function doErrorAsync () {
return timeoutReject(1000);
}
var log = (...args)=>console.log(...args);
var logErr = (...args)=>console.error(...args);
async function unpropogatedError () {
// promise is not awaited or returned so it does not propogate the error
doErrorAsync();
return "finished unpropogatedError successfully";
}
unpropogatedError().then(log).catch(logErr)
async function handledError () {
var start = Date.now();
try {
console.log((await doErrorAsync()) - start);
console.log("past error");
} catch (e) {
console.log("in catch we handled the error");
}
return "finished handledError successfully";
}
handledError().then(log).catch(logErr)
// example of how error propogates to chained catch method
async function propogatedError () {
var start = Date.now();
var time = await doErrorAsync() - start;
console.log(time - start);
return "finished propogatedError successfully";
}
// this is what prints propogatedError's error.
propogatedError().then(log).catch(logErr)
Jika Anda pergi ke sini, Anda dapat melihat proposal yang sudah jadi untuk versi ECMAScript mendatang.
Alternatif untuk ini yang dapat digunakan hanya dengan ES2015 (ES6) adalah dengan menggunakan fungsi khusus yang membungkus fungsi generator. Fungsi generator memiliki kata kunci hasil yang dapat digunakan untuk mereplikasi kata kunci yang menunggu dengan fungsi sekitarnya. Fungsi kata kunci dan generator hasil adalah tujuan yang jauh lebih umum dan dapat melakukan banyak hal lebih banyak daripada apa fungsi fungsi async menunggu. Jika Anda ingin pembungkus fungsi generator yang dapat digunakan untuk mereplikasi async, saya akan menunggu co.js . Ngomong-ngomong fungsi co sama seperti async menunggu fungsi mengembalikan janji. Jujur meskipun pada titik ini kompatibilitas browser hampir sama untuk fungsi generator dan fungsi async jadi jika Anda hanya ingin fungsi menunggu async Anda harus menggunakan fungsi Async tanpa co.js.
Dukungan browser sebenarnya cukup bagus sekarang untuk fungsi Async (pada 2017) di semua browser utama saat ini (Chrome, Safari, dan Edge) kecuali IE.