代码之家  ›  专栏  ›  技术社区  ›  Jerry Fanelli

按预期顺序检索GET请求响应时出现问题

  •  0
  • Jerry Fanelli  · 技术社区  · 7 年前

    关于我对异步函数的理解,我的javascript代码面临一些问题。

    我有一些大的txt文件要导入到我的javascript代码中,所有文件都在同一个域中。 例如,当我打开/index.php时,我希望javascript从位于/log/ip_number/log.txt中的几个文本文件加载文本。

    现在我用的是这样的东西:

    for (var i = 0; i < numberOfVPS; i++) {
        $.get("/log/"+ip_list[i]+"/log.txt", function(contents){
         //does my things with contents
         array.push(myOutput)
         });
    }
    

    在代码末尾,我应该得到一个按IP在IP列表数组中的顺序排序的数组….但这不是我所得到的,我真的不明白为什么…

    例如,我应该得到: 数组=[1,2,3,4,5]

    其中1、2、3、4和5与IP_列表[0]、IP_列表[1]、IP_列表[2]、IP_列表[3]、IP_列表[4]相关, 但我得到的是:

    数组=[2,5,3,1,4],每次我重新加载页面时都有不同的顺序…. 我认为这是因为javascript代码没有成功地加载文本文件,因此给了我一些无序的输出,但这只是我的观点,一个新手“程序员”的观点……

    请帮帮我!

    杰瑞

    3 回复  |  直到 7 年前
        1
  •  1
  •   nullqube    7 年前

    您的代码是异步的,因此您的一个选项是使用 Promise s 例如,你可以这样写:

    var files=[];
    对于(var n=0;n<numberofvps;n++){
    files[n]=$.get(“filepath”);
    }
    $.when(…files).done(function(){
    array.push(…参数);
    (});
    < /代码> 
    
    

    https://api.jquery.com/jquery.when/

    https://developer.mozilla.org/en-us/docs/web/javascript/reference/operators/spread_syntax

    https://davidwalsh.name/write-javascript-promises

    许诺S 例如,你可以这样写:

    var files = [];
    for( var n = 0; n < numberOfVPS; n++ ) {
       files[n] = $.get("FILEPATH");
    }
    $.when(...files).done(function(){
       array.push(...arguments);
    });
    

    https://api.jquery.com/jquery.when/

    https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax

    https://davidwalsh.name/write-javascript-promises

        2
  •  1
  •   colxi    7 年前

    一批GET请求并不总是以触发它们的相同顺序进行解析。

    您可以直接将.txt内容分配给相应的键,而不是将结果推送到数组中。

    array[i] = myOutput;
    

    但是因为 i 在get回调中,将不再与执行get请求时相同(循环中计数器不断增加),您需要生成一个新的作用域,其中 被保存下来。一 function 会给我们的。

    您还需要一种方法来知道最后一个文件何时被加载…要执行您的操作…

    let completed =0;
    
    const getTxt = function(i){
      $.get("/log/"+ip_list[i]+"/log.txt", contents=>{
        array[i] = myOutput;
        completed++
        if(completed === numberOfVPS){ 
          // all files have been loaded 
          yourCallbackHere();
        }
      });
    }
    
    for(let i = 0; i < numberOfVPS; i++) getTxt(i)
    

    我个人会使用承诺来实现这一点,它们将以更干净和直观的方式处理异步操作。

        3
  •  0
  •   Dave Anderson    7 年前

    循环进行异步调用以加载文件。顺序取决于回调函数加载文件后的执行时间。这将取决于文件的大小和网络延迟。

    如果需要对数组中的项进行排序,可以将对象存储在数组中并使用 Array.prototype.sort() 在所有回调完成后对对象进行排序。

    array.push({ index: i, ip: myOutput})
    
    array.sort(function(a, b) {
      return a.index - b.index;
    }
    

    要获得您使用的原始数组 Array.prototype.map() ;

    array.map(x => x.ip);