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

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

应该怎么做:

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

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

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

这是一种常见的情况。 请注意,通常不必按顺序处理呼叫。 通常只需发送带有ajax调用的上下文并将所有内容拼凑在一起,因为它是半随机出现的,如本答案中所示。


强制顺序行为的一种方法是通过complete函数链接调用。 这是演示该过程的全function代码 。 要使用,请在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] ]; } 

这通常输出:

处理索引0(q / 48 /)。 它的标题是:“HTML表单中的多个提交按钮 -  Stack Overflow”
获取指数1(q / 27 /)......
处理索引1(q / 27 /)。 它的标题是:“datetime  - 计算C#中的相对时间 -  Stack Overflow”
获取指数2(q / 34 /)......
处理索引2(q / 34 /)。 它的标题是:“flex  - 在Actionscript 3中卸载ByteArray  -  Stack Overflow”
获取指数3(q / 69 /)......
处理指数3(q / 69 /)。 它的标题是:“。net  - 如何用C#计算某人的年龄? -  Stack Overflow”
获取索引4(badpage)...
获取https://stackoverflow.com/badpage?_=1512087299126 404()
 Oopsie在索引4(badpage)! 错误对象{...

- 取决于您的Stack Overflow声誉。


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

使用异步ajax请求模拟for循环。 在ajax的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);