Dalam prototipe dukungan downlevel Async / Await saat ini, kami menemukan bug yang menyebabkan terjadinya pengecualian yang salah dalam kode yang seharusnya berfungsi.
Inti dari masalah ini adalah bahwa memiliki pernyataan "return" di dalam perulangan for dalam fungsi yang memiliki menunggu di dalamnya menyebabkan kesalahan .
Jalankan kode ini dan Anda akan melihat bahwa setiap kali "num" adalah> .5 (dan pernyataan "return true" dievaluasi), Anda mendapatkan kesalahan berikut yang berasal dari dalam kode __generator: “TypeError: Unable to get property '0' dari referensi tidak terdefinisi atau nol "
async function itemExists(): Q.Promise<boolean> {
var numTries = 3;
for (var i = 0; i < numTries; i++) {
var num = await Q.fcall(function() { return Math.random() });
console.log(num);
if (num > .5) {
return true;
}
}
return false;
}
itemExists().then(function(val) {
console.log("All values greater than .5: " + val)
}).catch(function(e) {
console.error("Error: " + e);
});
Masalahnya disebabkan oleh pernyataan "return" di dalam loop. Jika saya telah memodifikasi itemExists () untuk menyetel variabel lokal, misalnya, dan kemudian keluar dari loop melalui pernyataan "break", kode akan berfungsi:
// With workaround (NOT short-circuiting the loop)
async function itemExists(): Q.Promise<boolean> {
var numTries = 3;
var result = false;
for (var i = 0; i < numTries; i++) {
var num = await Q.fcall(function() { return Math.random() });
console.log(num);
if (num > .5) {
result = true;
break;
}
}
return result;
}
Analisis cepat dari masalah tersebut tampaknya ada dalam kode yang dihasilkan. Pengecualian dilemparkan di sini:
try {
var operation = body(state);
opcode = operation[0], arg = operation[1];
} catch (e) {
opcode = 1 /*throw*/, arg = e;
}
Tetapi pelakunya yang sebenarnya tampaknya dalam kenyataan bahwa ada ketidakkonsistenan dalam pernyataan pengembalian dan penghentian yang dihasilkan (sejauh yang saya tahu). Yakni, 3 terlihat seperti "istirahat" dan terkadang "kembali".
function itemExists() {
return new Q.Promise(function (_resolve) {
_resolve(__awaiter(__generator(function (_state) {
switch (_state.label) {
case 0:
numTries = 3;
i = 0;
_state.label = 1;
case 1:
if (!(i < numTries))
return [3 /*break*/, 4];
return [4 /*yield*/, Q.fcall(function () {
return Math.random();
})];
case 2:
num = _state.sent;
console.log(num);
if (num > .5) {
return [3 /*return*/, true];
}
_state.label = 3;
case 3:
i++;
return [3 /*break*/, 1];
case 4:
return [2 /*return*/, false];
}
})));
});
var numTries, i, num;
}
itemExists().then(function (val) {
console.log("All values greater than .5: " + val);
}).catch(function (e) {
console.error("Error: " + e);
});
Mesin negara ini terlihat seperti generator emisi tingkat bawah. Apakah ini berarti bahwa [email protected] akan mendukung yield
saat menargetkan es5?
@ d180cf kami sedang mengerjakannya :)
Seharusnya ini tidak lagi menjadi masalah pada 4685646, yang merupakan versi baru dari transformasi downlevel ini untuk fungsi asinkron yang kami targetkan untuk rilis 2.1 kami.
Komentar yang paling membantu
@ d180cf kami sedang mengerjakannya :)