0

我编写了一个自定义 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功能似乎在最后再次触发..

谁能给我一些关于让它工作的指示?

4

3 回答 3

0

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

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

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

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

更多信息可以在这里找到

希望这可以帮助!

于 2013-04-05T09:40:34.793 回答
0

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

于 2013-04-05T09:40:46.373 回答
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
});
于 2013-04-05T09:41:24.230 回答