如何顺序循环GET / POST调用(等待上一次)返回?

时间:2017-11-30 16:19:07

标签: javascript jquery userscripts tampermonkey

我正在为网页编写Tampermonkey脚本并尝试从其他页面提取数据。
我试图通过一个列表llcList创建一个内部循环的函数,并从ajax方法GET中检索数据,但是想要在转到第二个请求之前等待完成一个请求。
如果我可以让它等一些额外的时间,那就是奖金。

会发生什么:

  1. 发送对llcList [0]
  2. 的请求
  3. 获取返回数据,处理它
  4. 等一段时间
  5. 发送对llcList [1]
  6. 的新请求

    这可能吗?我尝试了几种方法,每次循环发送所有请求不是一秒钟。 :

    function F_Company_LLC(){
    for (i = 0; i < llcList.length;i++) {
            if(llcList[i][2]=="lab"){
                //run function 0
                //break;
            }
            else if(llcList[i][2]=="shop"){
                //run function 1
                //break;
            }
            else{
                F_GET_CompData(llcList, llcList[i][1],i,function(result){
                    console.log(result);
                });
            }
    }}
    
    function F_GET_CompData(F_GET_CompData_list, CompID, F_GET_CompData_row, callback){
    $.ajax({
        method : "GET",
        url: base_link+"/company/edit_company/"+CompID,
        beforeSend: function(){runningRequest++;},
        success: function(data){
    
      //data processing
    
            runningRequest--;
        },
        error: function() {console.log("Get_ComData");}
    });
    callback(runningRequest);}
    

2 个答案:

答案 0 :(得分:1)

这是常见的情况。请注意,虽然顺序处理呼叫通常是不必要的。通常只需发送带有ajax调用的上下文并将所有内容组合在一起,因为它是半随机的,如this answer所示。

强制顺序行为的一种方法是通过complete函数进行链接调用。这是演示流程的全功能代码。要使用,请在Stack Overflow页面上将其粘贴到浏览器控制台中。 :

var listO_pages = ["q/48/", "q/27/", "q/34/", "q/69/", "badpage"];
var numPages    = listO_pages.length;

getPageN (0);  //-- Kick off chained fetches

function getPageN (K) {
    if (K >= 0  &&  K < numPages) {
        let targPage = listO_pages[K];

        $.ajax ( {
            url:            "https://stackoverflow.com/" + targPage,
            context:        {arryIdx: K},  //  Object Helps handle K==0, and other things
            success:        processPage,
            complete:       finishUpRequest,
            error:          logError
        } );
    }
}

function processPage (sData, sStatus, jqXHR) {
    //-- Use DOMParser so that images and scripts don't get loaded (like jQuery methods would).
    var parser          = new DOMParser ();
    var doc             = parser.parseFromString (sData, "text/html");
    var payloadTable    = doc.querySelector ("title");
    var pageTitle       = "Not found!";
    if (payloadTable) {
        pageTitle       = payloadTable.textContent.trim ();
    }
    var [tIdx, tPage]   = getIdxAndPage (this);  // Set by `context` property

    console.log (`Processed index ${tIdx} (${tPage}). Its title was: "${pageTitle}"`);
}

function finishUpRequest (jqXHR, txtStatus) {
    var nextIdx     = this.arryIdx + 1;
    if (nextIdx < numPages) {
        var tPage   = listO_pages[nextIdx];
        //-- The setTimeout is seldom needed, but added here per OP's request.
        setTimeout ( function () {
            console.log (`Fetching index ${nextIdx} (${tPage})...`);
            getPageN (nextIdx);
        }, 222);
    }
}

function logError (jqXHR, txtStatus, txtError) {
    var [tIdx, tPage]   = getIdxAndPage (this);  // Set by `context` property
    console.error (`Oopsie at index ${tIdx} (${tPage})!`, txtStatus, txtError, jqXHR);
}

function getIdxAndPage (contextThis) {
    return [contextThis.arryIdx, listO_pages[contextThis.arryIdx] ];
}


这通常会输出:

Processed index 0 (q/48/). Its title was: "Multiple submit buttons in an HTML form - Stack Overflow"
Fetching index 1 (q/27/)...
Processed index 1 (q/27/). Its title was: "datetime - Calculate relative time in C# - Stack Overflow"
Fetching index 2 (q/34/)...
Processed index 2 (q/34/). Its title was: "flex - Unloading a ByteArray in Actionscript 3 - Stack Overflow"
Fetching index 3 (q/69/)...
Processed index 3 (q/69/). Its title was: ".net - How do I calculate someone's age in C#? - Stack Overflow"
Fetching index 4 (badpage)...
GET https://stackoverflow.com/badpage?_=1512087299126 404 ()
Oopsie at index 4 (badpage)! error  Object {...

- 取决于您的Stack Overflow声誉。

重要提示:请勿尝试使用async: false技术。这些只会:锁定浏览器,偶尔会使计算机崩溃,并使调试和部分结果更加困难。

答案 1 :(得分:-1)

使用异步ajax请求模拟for循环。在ajax&#39; complete callback上转到列表中的下一个项目:

function F_Company_LLC(llcList) {
    var i= 0;

    function getNext() {

           if(llcList[i][2]=="lab"){
                //run function 0

                    ++i;

                    getNext();
            }
            else if(llcList[i][2]=="shop"){
                //run function 1

                    ++i;

                    getNext();
            }
            else{

             $.ajax({

              url: base_link+"/company/edit_company/"+llcList[i][1], //CompID
              method: 'GET',
              async: true,
              success: function(data) {
                if (data.status == "success" && i <= llcList.length) {
                     //data processing
                 }
               },
               error: function(xhr) { 
                alert("Error while processing CompID: " + llcList[i][1]);

               },
              complete: function() {
             //complete executes after either 
             //the success or error callback were executed.
                     ++i;
                    getNext();//go to next item in the list
              },
             });      
            }  
    }

    getNext();
}


F_Company_LLC(llcList);