Javascript模块模式和jquery Ajax等问题

时间:2013-04-05 09:36:22

标签: javascript jquery wait module-pattern

我编写了一个自定义js模块,它基本上发送消息并需要等待响应才能继续:

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函数似乎在最后再次发生..

任何人都可以给我一些关于让它发挥作用的指示吗?

3 个答案:

答案 0 :(得分:0)

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

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

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

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

可以找到更多信息Here

希望这有帮助!

答案 1 :(得分:0)

问题可能与w变量的范围有关,因为在第二次调用时(在等待函数中,进入else分支),你正在破坏之前超时的引用已创建,因此clearTimeout无法工作:尝试在直接外部范围内定义它。

答案 2 :(得分: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
});