วิธีทำให้ Javascript setTimeout ส่งคืนค่าในฟังก์ชัน

ฉันมีฟังก์ชั่นที่เรียกใช้บริการบางอย่างและส่งคืนการตอบกลับ หากการตอบกลับเป็น FALSE ระบบจะรอ 1 วินาทีเพื่อถามบริการอีกครั้ง (ซึ่งอาจส่งคืน TRUE)

ฉันจะเรียกใช้ฟังก์ชัน "checkService()" หนึ่งครั้งและรับมูลค่าจริงได้อย่างไร (ลองครั้งแรกหรือครั้งที่สอง ตัดสินใจโดยฟังก์ชัน) ฉันตั้งค่า RET ภายในฟังก์ชัน แต่ฟังก์ชันจะส่งคืน RET แรกเสมอ เนื่องจาก setTimeout เป็นแบบอะซิงโครนัส

กล่าวอีกนัยหนึ่งฉันต้องการเคล็ดลับ "การนอนหลับ" หรือวิธีแก้ปัญหาใด ๆ (อาจเป็น jQuery เช่นกัน)

function checkService() {

  //this may return TRUE or FALSE
  var RET = someServiceResponse(); 

  // here waits 1 second, then ask the service again
  if( RET == true ) {
    return true;
  } else {

    setTimeout(
        function() {
            //it must return the second response of the service
            RET = someServiceResponse();  
        }, 
        1000
    );

    // I want the checkService() return the response after de timeout
    return RET;  
  }
}

function alertResponse() {
    alert( checkService() );
}

person Aberel    schedule 04.08.2014    source แหล่งที่มา
comment
someServiceResponse ได้รับผลลัพธ์จากการโทร ajax หรือไม่ นั่นอาจเป็นหัวใจของปัญหาของคุณ   -  person Travis J    schedule 05.08.2014
comment
แม้ว่าการรอ 1 วินาทีจะดูมีประโยชน์ แต่ก็อาจใช้งานไม่ได้หากการโทรกลับใช้เวลานานกว่านั้นในการกลับมา ฉันขอแนะนำให้แยกฟังก์ชันนี้ออกด้วยฟังก์ชันโทรกลับที่จะเริ่มทำงานเมื่อมีการตอบกลับจริง   -  person Bosworth99    schedule 05.08.2014
comment
ทราวิส ไม่ อย่างไรก็ตาม ฉันไม่รังเกียจหากการรอใช้เวลานานกว่า 1 วินาที เวลานั้นไม่สำคัญ แค่ต้องรอสักครู่ (ประมาณครึ่งวินาที) แล้วตรวจสอบอีกครั้ง   -  person Aberel    schedule 05.08.2014


คำตอบ (2)


คุณควรใช้ฟังก์ชันโทรกลับเมื่อคุณคาดหวังผลลัพธ์จากบริการ

แบบนี้ :

function checkService(callback) {

    //this may return TRUE or FALSE
    var RET = someServiceResponse();

    // here waits 1 second, then ask the service again
    if( RET == true ) {
        callback(RET);
    } else {

        setTimeout(
                function() {
                    //it must return the second response of the service
                    RET = someServiceResponse();
                    callback(RET);
                },
                1000
        );

        // I want the checkService() return the response after de timeout
        return RET;
    }
}

ดังนั้นเมื่อคุณต้องการเรียกใช้บริการ คุณเพียงแค่ต้องทำ:

checkService(function(status){
    alert(status);

    // Here some code after the webservice response
});
person Raphaël Malié    schedule 04.08.2014
comment
หรือโทร checkService() อีกครั้งในฟังก์ชันหมดเวลา ควรทำงานด้วยวิธีใดวิธีหนึ่ง - person Rebirth; 05.08.2014
comment
ฉันใช้ alert() เพื่อทำให้สิ่งนี้ง่ายขึ้น จริงๆ แล้วฉันต้องเรียก checkService() จากฟังก์ชันอื่นๆ มากมายในโค้ดของฉัน และทำทุกอย่างที่จำเป็นตามการตอบสนองของ checkService() ถ้าฉันโทรอีกครั้งจากภายนอก ฉันจะทำแบบเดียวกับที่ checkService() ทำ นั่นเป็นเพราะฉันสร้างฟังก์ชัน checkService() - person Aberel; 05.08.2014

Googling 'javascript setTimeout callback' นี่คือ jsFiddle ที่มีประโยชน์ประมาณ 3 ผลลัพธ์:

getData('http://fakedomain1234.com/userlist', writeData);

document.getElementById('output').innerHTML += "show this before data ...";

function getData(dataURI, callback) {
    // Normally you would actually connect to a server here.
    // We're just going to simulate a 3-second delay.
    var timer = setTimeout(function () {
        var dataArray = [123, 456, 789, 012, 345, 678];
        callback(dataArray);
    }, 3000);
}

function writeData(myData) {
    console.log(myData);
}

http://jsfiddle.net/cwbuecheler/Y9Ca8/

person elzi    schedule 04.08.2014