Typescript: Bug di async / await saat melakukan pernyataan "return" di dalam perulangan for yang menunggu di fungsi asinkron

Dibuat pada 19 Agu 2015  ·  3Komentar  ·  Sumber: microsoft/TypeScript

Dalam prototipe dukungan downlevel Async / Await saat ini, kami menemukan bug yang menyebabkan terjadinya pengecualian yang salah dalam kode yang seharusnya berfungsi.

Repro:

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);
    });

Analisis:

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);
});
Bug Fixed

Komentar yang paling membantu

@ d180cf kami sedang mengerjakannya :)

Semua 3 komentar

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.

Apakah halaman ini membantu?
0 / 5 - 0 peringkat

Masalah terkait

remojansen picture remojansen  ·  3Komentar

kyasbal-1994 picture kyasbal-1994  ·  3Komentar

CyrusNajmabadi picture CyrusNajmabadi  ·  3Komentar

dlaberge picture dlaberge  ·  3Komentar

siddjain picture siddjain  ·  3Komentar