2013-04-05 60 views
0

我写了基本发送消息,并需要等待,为了响应继续自定义JS模块:的Javascript模块模式和jQuery阿贾克斯等待问题

var manageBooking = (function (jQ) { 

//decalre private variables 
var domain, msgRecieved, msgResponse, validationValue; 
//decalre private functions 
var sendMessage, wait; 

// A private variables 
domain = document.domain; 
msgRecieved = false; 
msgResponse = null; 


wait = function(timeOutStep){ 
    var w; 
    console.log('msgRecieved', msgRecieved); 
    if (msgRecieved === true) { 
     clearTimeout(w); 
     return; 
    } else { 
     console.log('waiting..'); 
     w = setTimeout(wait, timeOutStep, timeOutStep); 
    } 
} 

// A private function to send messages 
sendMessage = function(requestURL, data, type) { 
    console.log(requestURL); 
    console.log(data); 
    console.log(type); 
    //reset vars to defaults 
    msgRecieved = false; 
    msgResponse = null; 
    jQuery.ajax({ 
     url: "http://"+domain+"/_ajax/"+requestURL, 
     dataType: "html", 
     async: true, 
     data: data, 
     type: type, 
     success: function(msg){ 
      console.log(msg); 
      msgResponse = msg; 
      msgRecieved = true; 
     } 
    }); 
    console.log('after ajax call'); 
    wait(500); 
    console.log('after wait'); 
    console.log('msgRecieved', msgRecieved); 
    return; 
}; 
return { 

// A public variable 
errorMsg: "", 
validationName: "", 
bookingID: "", 
output: "", 
// A public function to login 
login: function(enteredBookingID, enteredSurname) { 
    // Call private sendMsg 
    sendMessage("user_login/"+enteredBookingID+"/"+enteredSurname, null, 'GET'); 
    console.log(msgResponse); 
    throw "error"; 
    //check response 
    var patt=/Sorry/i; 
    //test pattern 
    var result=patt.test($.trim(msgResponse)); 
    //if false OK 
    if (result === false) { 
     var split = msgResponse.split('|'); 
     validationName = split[0]; 
     validationValue = split[1]; 
     bookingID = enteredBookingID 
     return true; 
    } 
    //else error 
    errorMsg = msgResponse; 
    return false; 
} 
}; 
})(jQuery); 
manageBooking.login(123,123); 

我有被强迫sendMessage问题函数等待ajax完成并将msgRecieved设置为true。

但是看起来sendMessage函数碰到wait函数一次,然后继续。 以下控制台输出显示事件的顺序:

GET http://website/_ajax/user_login/123/123 
after ajax call //sendMessage() 
msgRecieved, false //wait() 
waiting.. //wait() 
after wait //sendMessage() 
msgRecieved, false //sendMessage() 
null//login() 
uncaught exception: error //login() 
<p>Sorry, we cannot locate your details. </p> <!-- jQuery Ajax call --> 
msgRecieved, true //wait() 

我很困惑与是,wait功能似乎就在年底再次火..

谁能给我让一些指针这工作?

+0

使用回调,而不是对抗的方式战斗的JavaScript编程预期要:) – 2013-04-05 10:06:58

回答

0

JavaScript的行为方式是异步的,意思是它不会等待

你在你的代码的一部分,看起来像这样:

jQuery.ajax({ 
    url: "http://"+domain+"/_ajax/"+requestURL, 
    dataType: "html", 
    async: true, 
    data: data, 
    type: type, 
    success: function(msg){ 
     console.log(msg); 
     msgResponse = msg; 
     msgRecieved = true; 
    } 
}); 

您应该将代码时的响应success函数内到达运行,像这样:

success : function (msg) { 
    handleMessage(msg); // Or any other manipulation to the received message 
} 

function handleMessage(msg) { 
    // Work with your received message here. 
} 

success将会调用收到的消息,这是一个回调。

实施sendMessage将通过以下方式正确方法:

sendMessage = function(requestURL, data, type, callback) { 
    console.log(requestURL); 
    console.log(data); 
    console.log(type); 
    //reset vars to defaults 
    msgRecieved = false; 
    msgResponse = null; 
    jQuery.ajax({ 
     url: "http://"+domain+"/_ajax/"+requestURL, 
     dataType: "html", 
     async: true, 
     data: data, 
     type: type, 
     success: function(msg){ 
      console.log(msg); 
      msgResponse = msg; 
      msgRecieved = true; 
      // Call the callback function to notify the message 
      // was received 
      callback(); 
     } 
    }); 
}; 

,然后使用它像这样:

sendMessage(urlHere, dataHere, typeHere, function() { 
    // Message has been received, msgResponse and msgReceived 
    // have already been updated. Do what you need here 
}); 
+0

嗨,我知道它不会等待 - 即时试图强制它。原因是我只在页面上有1个Ajax调用,而其他函数使用它,而不必为每个函数定义一个新的Ajax调用 - 例如不重复代码。 – 2013-04-05 09:52:46

+0

更进一步,我已经得到js在全球范围内像上述工作 - 但即时通讯试图在'manageBooking'范围内做这个废品,它是在jquery.ajax成功函数内。 – 2013-04-05 09:57:31

+0

我明白了。那么,在JavaScript中确实没有必要这样做,如果你喜欢,你可以保持事件循环的繁忙(像while(timePassed <500){}),但它只是消耗资源而不是空闲。方法本地使JavaScript等待在空闲状态 – 2013-04-05 09:58:25

0

您应该尝试使用JavaScript setInterval函数代替setTimeout。但是这一次,请分解sendMessage,并且在接收到ajax消息之后将需要执行的部分放置在setInterval下。

一旦接收到ajax消息,sendMessage的第二部分就会运行(在messagereceived为true之后),并且还会清除间隔。

这是因为setTimeout()只在设定的时间间隔后执行一次。

setInterval()重复执行exery间隔直到它被清除。

的更多信息,可以发现Here

希望这有助于!

+0

嗨,谢谢,我试过但仍然没有运气 - 仍然似乎只是运行过去.. – 2013-04-05 09:53:08

0

该问题可能与w变量的范围有关,因为在第二次调用时(在等待函数中,在您的else分支中),您正在销毁对之前创建的超时的引用,所以clearTimeout可以'工作:尝试在直接的外部范围内定义它。

+0

这确实允许它循环,因为我的预期,但它仍然只是这样做后代码继续回到'登录'功能.. – 2013-04-05 09:53:45