How to loop through GET/POST calls sequentially (waiting for previous) return?

*爱你&永不变心* 提交于 2019-12-20 04:35:06

问题


I'm writing a Tampermonkey script for a web page and trying to extract data from other pages.
I'm trying to make a function that has a loop inside that goes thru a list, llcList, and retrieves data from ajax method GET, but would like to wait for to finish one request before going to second one.
Bonus would be if I could make it wait some extra time.

What should happen:

  1. send request for a llcList[0]
  2. get return data, process it
  3. wait some time
  4. send new request for a llcList[1]

Is this possible? I tried few methods, every time loop send all requests not a second apart. :

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);}

回答1:


This is a common scenario. Note that it's often unnecessary to process the calls sequentially though. It's usually adequate to just send context with the ajax calls and piece everything together as it comes in semi randomly, as shown in this answer.


One way to force sequential behavior is to chain calls via the complete function. Here is fully functional code that demonstrates the process. To use, paste it into your browser console while on a Stack Overflow page. :

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] ];
}


This typically outputs:

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 {...

-- depending on your Stack Overflow reputation.


Important: Do not attempt to use async: false techniques. These will just: lock up your browser, occasionally crash your computer, and make debug and partial results much harder.




回答2:


Simulate for-loop with async ajax requests. On ajax's complete callback go to next item in the list:

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);


来源:https://stackoverflow.com/questions/47577946/how-to-loop-through-get-post-calls-sequentially-waiting-for-previous-return

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!