2017-11-30 2 views
1

Ich schreibe ein Tampermonkey-Skript für eine Webseite und versuche, Daten von anderen Seiten zu extrahieren.
Ich versuche, eine Funktion zu machen, die eine Schleife hat, die durch eine Liste geht, llcList, und ruft Daten von Ajax-Methode GET ab, möchte aber warten, um eine Anforderung zu beenden, bevor zu zweit gehen.
Bonus wäre, wenn ich es einige zusätzliche Zeit warten lassen könnte.Wie durchlaufen GET/POST-Anrufe nacheinander (warten auf vorherige) Rückkehr?

Was soll passieren:

  1. Sendeauftrag für eine llcList [0]
  2. get Rückgabedaten, zu verarbeiten
  3. einige Zeit warten
  4. neue Anforderung für eine llcList [1]
  5. senden

Ist das möglich? Ich habe einige Methoden ausprobiert, jedes Mal, wenn eine Schleife alle Anfragen sendet, die nicht eine Sekunde auseinander liegen. :

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

Vermeiden Sie im Allgemeinen Ajax-Aufrufe innerhalb von Schleifen. Recherchiere alternative Lösungen, bei denen du einen einzelnen Ajax-Aufruf mit genügend Informationen machst, um mehrere Datensätze zu aktualisieren, alle Datensätze, die mit mehreren Firmen-IDs übereinstimmen oder was auch immer du machen möchtest, etc .. Allerdings denke ich eine While-Schleife mit kompletten Callbacks oder Versprechungen zu bestimmen, wann es weitergehen könnte, könnte funktionieren? Aber was, wenn der Anruf nicht zurückkehrt und schließlich ausläuft, machen Sie weiter oder nicht? - Ich würde eher nach einer Lösung suchen, die mehrere Datensätze bei einem Aufruf zurückgibt. – Nope

+0

Ich aktualisierte Code für einen Punkt 3. Jetzt Funktion LLC_Comp_Timer ausführen, inkrementieren Variable i um eins und warten auf 1 Sekunde vor der erneuten Ausführung – user9034751

Antwort

1

Dies ist ein gängiges Szenario. Beachten Sie, dass es oft nicht notwendig ist, die Anrufe sequenziell zu verarbeiten. Es ist normalerweise ausreichend, nur den Kontext mit den Ajax-Aufrufen zu senden und alles zusammenzufassen, da es halb zufällig kommt, wie in this answer gezeigt.


Eine Möglichkeit, sequentielles Verhalten zu zwingen Ketten Anrufe über die complete Funktion. Hier ist voll funktionsfähigen Code, der den Prozess zeigt. Um es zu verwenden, fügen Sie es auf einer Stapelüberlaufseite in Ihre Browserkonsole ein. :

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


Diese Regel gibt:

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

- abhängig von Ihrem Stack Overflow Ruf.


Wichtig: Versuchen Sie nicht async: false Techniken zu verwenden. Dies wird nur: Sperren Sie Ihren Browser, gelegentlich Absturz Ihres Computers und Debugging und teilweise Ergebnisse viel schwieriger machen.

+0

Sie verwenden Async True. Ajax-Anfrage ist standardmäßig async true –

+0

@javaguy, das war ein Tippfehler, wie war mein letzter Kommentar zu Ihrem Beitrag; Es tut uns leid. Asynchroner Code ist der Weg zu gehen. ... Den Mangel an Doppel-Negativen nicht zu vermeiden, ist nicht * immer * schwer. ;) –

+0

Ja, ich stimme zu. Meine Implementierung verwendet Async-Aufrufe. –

-1

Simulieren Sie For-Schleife mit asynchronen AJAX-Anforderungen. Auf complete callback Gos Ajax zum nächsten Element in der Liste:

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

Das ist zerbrechlich und unzuverlässig. Was ist, wenn das Netzwerk oder die abgefragte Datenbank vorübergehend verlangsamt wird und die Zeitüberschreitung nicht ausreicht? Es ist ein Ratespiel.Etwas Konkreteres wie Versprechungen zu verwenden oder einen einzigen Anruf nur außerhalb der Schleife zu machen wäre viel zuverlässiger. Code sieht so aus, als ob die Schleife eine Liste von Bezeichnern erstellen kann, deren Firmendetails in einer einzelnen Abfrage zurückgegeben werden können. – Nope

+0

Das setTimeout ist die zusätzliche Zeit, die @ user9034751 benötigt. ** Es ist nicht die Wartezeit für die Anfrage **. Wenn das Netzwerk oder die abgefragte Datenbank eine vorübergehende Verlangsamung erfährt, wird error: function() automatisch von $ .ajax ausgeführt und Sie können damit umgehen ("no internet" -Nachricht für den Benutzer anzeigen). –

+0

Sie haben Recht, dass eine einzelne Anfrage besser ist, aber @ user9034751 fragt nach der Implementierung mehrerer Anfragen. –

Verwandte Themen