Typescript: خطأ في غير متزامن / انتظار عند تنفيذ عبارة "return" داخل حلقة for التي تنتظر في دالة غير متزامنة

تم إنشاؤها على ١٩ أغسطس ٢٠١٥  ·  3تعليقات  ·  مصدر: microsoft/TypeScript

في النموذج الأولي الحالي لدعم Async / Await ذي المستوى الأدنى ، وجدنا خطأ يتسبب في حدوث استثناء خاطئ في التعليمات البرمجية التي يجب أن تعمل بخلاف ذلك.

ريبرو:

جوهر المشكلة هو أن وجود تعليمة "return" داخل حلقة for في دالة انتظار فيها يؤدي إلى حدوث خطأ .

شغّل هذا الرمز وستلاحظ أنه عندما يكون "num"> .5 (ويتم تقييم عبارة "return true") ، ستحصل على الخطأ التالي الذي يأتي من داخل رمز __generator: "TypeError: Unable to get property "0" لمرجع غير محدد أو فارغ "

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

تحليل:

سبب المشكلة هو عبارة "return" داخل الحلقة. إذا قمت بتعديل itemExists () لتعيين متغير محلي ، على سبيل المثال ، ثم الخروج من الحلقة عبر تعليمة "break" ، فستعمل الكود:

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

يبدو أن هناك تحليل سريع للمشكلة في الكود الذي تم إنشاؤه. الاستثناء هنا:

            try {
                var operation = body(state);
                opcode = operation[0], arg = operation[1];
            } catch (e) {
                opcode = 1 /*throw*/, arg = e;
            }

لكن يبدو أن الجاني الفعلي يكمن في حقيقة أن هناك عدم اتساق في بيان العودة والكسر (بقدر ما أستطيع أن أقول). وبالتحديد ، 3 تبدو أحيانًا "استراحة" وأحيانًا "عودة".

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

التعليق الأكثر فائدة

@ d180cf نحن نعمل على ذلك :)

ال 3 كومينتر

تبدو آلة الحالة هذه وكأنها انبعاث منخفض المستوى للمولدات. هل هذا يعني أن [email protected] سيدعم yield عند استهداف es5؟

@ d180cf نحن نعمل على ذلك :)

يجب ألا تكون هذه مشكلة اعتبارًا من 4685646 ، وهو الإصدار الجديد من هذه التحولات ذات المستوى الأدنى للوظائف غير المتزامنة التي نستهدفها لإصدارنا 2.1.

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات

القضايا ذات الصلة

MartynasZilinskas picture MartynasZilinskas  ·  3تعليقات

kyasbal-1994 picture kyasbal-1994  ·  3تعليقات

Antony-Jones picture Antony-Jones  ·  3تعليقات

DanielRosenwasser picture DanielRosenwasser  ·  3تعليقات

siddjain picture siddjain  ·  3تعليقات