for循环中的javascript异步调用

时间:2016-02-11 17:04:35

标签: javascript tampermonkey

菜鸟问题。它可能是一个可能的重复,但我无法解决如何重构代码。我应该如何构造下面的代码,以便控制台打印以下内容:

Here1 Here2 Here1 Here2 Here1 Here2

现在好了:

Here1 Here1 Here1 Here2 Here2 Here2

感谢您的帮助。

var record;

for ( i = 0; i < 3; i++ ) {
    sendRequest(selectTestsToRun('something1'), 'someTest1');
}

this.someTest1 = function(resObj, testToRun){
    console.log('Here1');
    record = resObj.value;
    sendRequest(selectTestsToRun('something2'), 'someTest2');
};

this.someTest2  = function(resObj, testToRun){
    console.log('Here2');
};

function selectTestsToRun(toDo){
    var data;

    switch( toDo) {
        case 'something1':
            data = 'postMessage';
            break;

        case 'something2':
            data = 'postMessage'+record;
            break;
    }

    return data;
}

function sendRequest(data , toDo ){

    GM_xmlhttpRequest({
        method: 'POST',
        url:  url,
        data: data,
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded'
        },
        onload: function(response) {
            var resObj = JSON.parse(response);
            this[toDo](resObj,toDo);
        }
    });

}

2 个答案:

答案 0 :(得分:1)

您根本不想要for循环。相反,您希望someTest2启动&#34;循环&#34;的下一次迭代:

var i = 0;
next();

function next() {
    if (i < 3) {
        sendRequest(selectTestsToRun('something1'), 'someTest1');
        ++i;
    }
}

this.someTest2  = function(resObj, testToRun){
    console.log('Here2');
    next();                                          // <==== Note
};

在上文中,我已将其烘焙到someTest2,但您当然可以通过回调将循环与someTest2分离。

答案 1 :(得分:0)

你必须记住,当循环同步执行时,AJAX调用是异步发生的。

循环调用test1背靠背,而AJAX请求需要至少300ms来往返服务器。这肯定会在循环结束很久之后发生。

您需要使用回调(或承诺)来调用下一个函数。您可以放置​​逻辑,以确定在回叫中下一个呼叫的逻辑。以下是使用jQuery进行Ajax通信的示例。

我去了旧学校并使用了一个只有第一个调用函数增加的计数器。当计数器达到极限时,它就像一个开关,停止粘性循环。

您可以在此处查看:https:// jsbin.com/wohife/

$(document).ready(function() {

    var counter = 0;


    function test1() {
        if (counter < 3) {
            sendRequest(1);
            console.log('here 1');
        }

        counter++;
    }

    function test2() {
        sendRequest(2);
        console.log('here 2');
    }

    function sendRequest(requesterId) {
        $.ajax({
            url: 'https://jsbin.com/sohefe/1.json',
            type: 'GET'
        })
        .success(function(data, status, req) {

            if (requesterId === 1) {
                test2();
            }
            else {
                test1();
            }

        });
    }

    test1();
});