في النموذج الأولي الحالي لدعم 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);
});
تبدو آلة الحالة هذه وكأنها انبعاث منخفض المستوى للمولدات. هل هذا يعني أن [email protected] سيدعم yield
عند استهداف es5؟
@ d180cf نحن نعمل على ذلك :)
يجب ألا تكون هذه مشكلة اعتبارًا من 4685646 ، وهو الإصدار الجديد من هذه التحولات ذات المستوى الأدنى للوظائف غير المتزامنة التي نستهدفها لإصدارنا 2.1.
التعليق الأكثر فائدة
@ d180cf نحن نعمل على ذلك :)