Saya membaca bahwa fungsi asinkron yang ditandai dengan async
kata kunci secara implisit mengembalikan sebuah janji:
async function getVal(){
return await doSomethingAync();
}
var ret = getVal();
console.log(ret);
tapi itu tidak koheren ... dengan asumsi doSomethingAsync()
mengembalikan sebuah janji, dan kata kunci await akan mengembalikan nilai dari janji, bukan dari janji itsef, maka fungsi getVal saya harus mengembalikan nilai itu, bukan janji implisit.
Jadi apa sebenarnya masalahnya? Apakah fungsi yang ditandai oleh kata kunci async secara implisit mengembalikan promise atau kita mengontrol apa yang dikembalikan?
Mungkin jika kita tidak secara eksplisit mengembalikan sesuatu, maka mereka secara implisit mengembalikan janji ...?
Untuk lebih jelasnya, ada perbedaan antara di atas dan
function doSomethingAync(charlie) {
return new Promise(function (resolve) {
setTimeout(function () {
resolve(charlie || 'yikes');
}, 100);
})
}
async function getVal(){
var val = await doSomethingAync(); // val is not a promise
console.log(val); // logs 'yikes' or whatever
return val; // but this returns a promise
}
var ret = getVal();
console.log(ret); //logs a promise
Dalam sinopsis saya, perilaku tersebut memang tidak konsisten dengan pernyataan pengembalian tradisional. Tampaknya saat Anda secara eksplisit mengembalikan nilai non-promise dari suatu async
fungsi, ini akan memaksa membungkusnya dalam sebuah promise. Saya tidak punya masalah besar dengan itu, tapi itu menentang JS normal.
sumber
console.log
diperlihatkan?Jawaban:
Nilai pengembalian akan selalu menjadi janji. Jika Anda tidak secara eksplisit mengembalikan janji, nilai yang Anda kembalikan secara otomatis akan digabungkan dalam sebuah janji.
Hal yang sama meskipun ada
await
.Promises auto-unwrap, jadi jika Anda mengembalikan promise untuk nilai dari dalam suatu
async
fungsi, Anda akan menerima promise untuk nilainya (bukan promise untuk promise untuk nilainya).ES6 memiliki fungsi yang tidak mengembalikan nilai yang sama persis dengan
return
. Fungsi-fungsi ini disebut generator.sumber
Saya melihat spesifikasi dan menemukan informasi berikut. Versi singkatnya adalah
async function
desugars ke generator yang menghasilkanPromise
s. Jadi, ya, fungsi asinkron mengembalikan janji .Menurut spesifikasi tc39 , berikut ini adalah benar:
Desugars untuk:
Di mana
spawn
"adalah panggilan ke algoritme berikut":sumber
async function
denganasync function*
. Yang pertama hanya membalas janji. Yang terakhir mengembalikan generator yang menghasilkan promise.Cukup tambahkan await before function Anda saat Anda memanggilnya:
sumber
async tidak mengembalikan promise, kata kunci await menunggu penyelesaian promise. async adalah fungsi generator yang disempurnakan dan menunggu berfungsi seperti hasil
Saya pikir sintaksnya (saya tidak 100% yakin) adalah
async function* getVal() {...}
Fungsi generator ES2016 bekerja seperti ini. Saya telah membuat database handler yang berbasis di atas membosankan yang Anda program seperti ini
Perhatikan bagaimana saya memprogramnya seperti sinkron biasa terutama di
yield connection.execSql
dan padayield connection.callProcedure
Fungsi db.exec adalah generator berbasis Promise yang cukup tipikal
sumber