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

后端 未结 2 1529
猫巷女王i
猫巷女王i 2021-01-25 08:17

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, <

2条回答
  •  情话喂你
    2021-01-25 08:37

    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.

提交回复
热议问题