ปกติ function ทั่วๆไปที่เราเรียก เราสามารถรอรับผลัพท์ ดังตัวอย่างเช่น
var gradeThai = calcGrade(80);
var gradeEng = calcGrade(67);
var average = avg(gradeThai,gradeEng);
เรียกฟังก์ชัน calcGrade โดยส่งคะเเนน 80 เข้าไป โดย return ของฟังก์ชันที่ได้กลับออกมา คือผลลัพท์เกรด A เก็บไว้ที่ตัวเเปรชื่อ gradeThai เป็นต้นซึ่งเป็น code ปกติที่เราเข้าใจเเละใช้กัน
เเต่เมื่อใดถ้า code ภายใน function calcGrade มีการใช้ setTimeout หรือมีการใช้ setInterval จะไม่สามารถรอผลลัพท์ ที่ต้วเเปร gradeThai มันจะวิ่งไปทำงาน code บรรทัดถัดไป ไม่รอฟังก์ชัน
calcGrade ทำงานจนเสร็จ สาเหตุเป็นเพราะ javascript มีเพียง thread เดียว จึงไม่สามารถรอการทำงาน ที่หน่างเวลาจากการใช้ setTimeout/setInterval ผมหาเจอใน google วิธีที่จะส่งผลลัพท์ออกไป
จากฟังก์ชัน ที่ภายในมีการใช้ setTimeout,setInterval จากตัวอย่างด้านล่างนี้
โค้ด: เลือกทั้งหมด
<html>
<head>
</head>
<body>
<form>
<a href="#" id="btn" onclick="ReadDevice();">อ่านบัตรประชาชน</a>
</form>
</body>
</html>
โค้ด: เลือกทั้งหมด
<script type="text/javascript">
var objOutput = null;
function ReadDevice()
{
//สับขาหลอกที่ตัวแปรก data ยังไงก็ไม่ได้ ค่ากลับมาอยู่แล้ว / นำค่าที่อ่านจากบัตรได้ส่งออกไปที่ฟังก์ชันที่ชื่อว่า callback
var data = stepMain(3,callback);
}
function stepMain(max,callback)
{
//วนลูปทุกๆ 0.5 วินาที เพื่อไปอ่านข้อมูลในเครื่องอ่านบัตรประชาชน โดยวนลุปมากสุด 3 ครั้ง
//เมื่อ objOutput มีค่า แสดงว่าอ่านข้อมูลจากบัตรได้แล้ว ก็ clearInterval เพื่อหยุดการวนรอบ และ ส่งผลลัพท์ออกไปยัง function callback เพื่อทำงานต่อไป
var i = 1;
var inv = setInterval(function () {
if ((i < max) && (objOutput == null)) {
stepRetrive();
i++;
}
else {
clearInterval(inv);
callback(objOutput);
}
}, 500);
}
function stepRetrive()
{
//รอ 3 วินาทีให้อุปกรณ์อ่านบัตรพร้อมใช้งาน เมื่อครบ 3 วินาทีแล้ว ก็อ่านข้อมูลจากบัตร
setTimeout(function () {
objOutput = cardReader.getAllFieldData();
}, 3000);
}
var callback = function (retVal) {
if (retVal != null) {
$("#txtIdNo").val(retVal.idNo);
$("#txtFirstName").val(retVal.nameThai);
$("#txtLastName").val(retVal.surNameThai);
//เป็นต้น
}
};
</script>