Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/427.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用Javascript/AJAX按特定顺序加载多个文件的内容_Javascript_Json_Ajax - Fatal编程技术网

如何使用Javascript/AJAX按特定顺序加载多个文件的内容

如何使用Javascript/AJAX按特定顺序加载多个文件的内容,javascript,json,ajax,Javascript,Json,Ajax,我使用JS/AJAX在一个页面上显示多个文件的内容。这些文件是动态生成的,并使用for循环加载。有一个文件包含集合的元数据,包括需要加载的其他文件的数量。其他文件的文件名中有一个数字,我通过请求“file_0;[loop_index].json”来加载它们 问题是,每个json文件中的数据量也是任意的,AJAX调用将以最小文件的顺序首先完成。我希望根据名称而不是大小按顺序显示数据 下面是一个简化的示例,假设我们要显示一本书的内容: function get(url) { return new

我使用JS/AJAX在一个页面上显示多个文件的内容。这些文件是动态生成的,并使用for循环加载。有一个文件包含集合的元数据,包括需要加载的其他文件的数量。其他文件的文件名中有一个数字,我通过请求“file_0;[loop_index].json”来加载它们

问题是,每个json文件中的数据量也是任意的,AJAX调用将以最小文件的顺序首先完成。我希望根据名称而不是大小按顺序显示数据

下面是一个简化的示例,假设我们要显示一本书的内容:

function get(url) {
  return new Promise(function(resolve, reject) {
    var req = new XMLHttpRequest();
    req.open('GET', url);

    req.onload = function() {
      if (req.status == 200) {
        resolve(req.response);
      }
      else {
        reject(Error(req.statusText));
      }
    };

    req.onerror = function() {
      reject(Error("Network Error"));
    };

    req.send();
  });
}

get('toc.json').then(function(response) {
  chapters = JSON.parse(response)["chapters"];
  return chapters;
}).then(function(levels) {
  for (i = 0; i < chapters; i++) {
    (function (i) {
      get("chap".concat(i,".json")).then(function(response) {
      console.log(response);

  })
  }(i));
  }
  });
第0.6章:

{ "text" : "00000" }
第1.1章:

{ "text" : "1" }
结果将是:

{ "text" : "1" }
{ "text" : "00000" }
如果我切换每个文件中的字符数,结果将是:

{ "text" : "0" }
{ "text" : "11111" }
我想打印在“1”行之前带有“0”的行,而不管每个文件大小

我不能使用async/await,因为我的页面必须在IE11中工作,并且它不支持箭头函数

我想到的解决方案是将内容存储在一个数组中,从for循环返回,然后显示内容,即:

尝试的解决方案:

var tempArray = [];

function get(url) {
  return new Promise(function(resolve, reject) {
    var req = new XMLHttpRequest();
    req.open('GET', url);

    req.onload = function() {
      if (req.status == 200) {
        resolve(req.response);
      } else {
        reject(Error(req.statusText));
      }
    };

    req.onerror = function() {
      reject(Error("Network Error"));
    };

    req.send();
  });
}

get('toc.json').then(function(response) {
  chapters = JSON.parse(response)["chapters"];
  return chapters;
}).then(function(levels) {
  for (i = 0; i < chapters; i++) {
    (function(i) {
      get("chap".concat(i, ".json")).then(function(response) {
        console.log(response);
        tempArray[i] = response;

      })
    }(i));
  }
  return tempArray;
}).then(function(response) {
    console.log(response);
  }

);
我认为这是失败的,因为承诺序列在实际AJAX调用完成之前经过for循环部分。如果我能想出如何让它等待他们完成,我会在那里,但此刻我被难住了

另一种在其他情况下可以工作的解决方案是动态生成部分html,并用相应的文件内容更新正确的元素。不幸的是,对于我的特定用例,这不是一个选项


有什么帮助吗?谢谢你。

竭尽全力使用承诺。为什么不将名称放在一个数组中,让一个函数执行获取、更新计数器并再次调用该函数

var listOfFiles=["fileList.txt”],
    cnt=0, 
    oReq = new XMLHttpRequest();

function reqListener () {
  if (listOfFiles[0]=="fileList.txt") {
    listOfFiles = this.responseText.split(",");
  }
  else { 
    processFile(this.responseText);
    cnt++;
  }
  getFile();
}

oReq.addEventListener("load", reqListener);
function getFile() { 
  if (cnt >= listOfFiles.length) return; 
  oReq.open("GET", listOfFiles[cnt]);
  oReq.send(); 
} 
getFile();
使用(从示例中删除XHR,但仍然使用承诺)

函数getTOC(){ var jsonStr=JSON.stringify({ 第二章, }); 返回承诺。解决(jsonStr); } 第(一)章的职能{ 返还承诺。决议(“第“+i章”); } getTOC() .然后(功能(响应){ var chapters=JSON.parse(响应)[“chapters”]; 返回章节; }) .然后(功能(章节){ var承诺=[]; 对于(i=0;i<章节;i++){ 承诺.推动(第一章);; } 返回承诺。全部(承诺); }) .然后(函数(结果){ //结果是一个结果数组,按预期顺序排列 控制台日志(结果); });
如果确实需要按特定顺序加载,则不希望使用异步请求。改用同步请求@Mikefullender你真的在推荐同步AJAX吗?正如你链接到的那篇文章所提到的,由于它所带来的糟糕的用户体验,一些主要的浏览器已经弃用了它,所以它很有可能在将来被删除。该页面明确表示“建议开发人员远离API。”虽然没有提到Chrome,但他们也不赞成使用它。除了创建一个糟糕的用户体验,它也不能被依赖(中期)。@MikeFurlender我建议不要使用同步请求。这将使浏览器无响应。我没有意识到同步XMLHttpRequests正在阻塞。很高兴知道。在这种情况下,将order索引传递给ajax请求,并使用order索引作为键将响应写入对象。当所有的承诺都解决时,使用键组合对象中的值来强制执行顺序。我目前正在尝试调整这个答案,看看它是否适合我。主要问题是listOfFiles中的文件数量可能会改变,我目前正在使用AJAX调用在开始循环数据文件之前获取该列表。对于如何处理这个问题,你有什么建议吗?为了让它正常工作,我不得不对它进行更多的调整,特别是我不得不将“ListOfFiles”重命名为“fileList”,不确定这是否是你的意思。但一旦我明白了这一点,它确实解决了问题。这可能会奏效,除非我在发布这个问题后意识到承诺/承诺。所有这些都不受IE11的支持,我提到我需要能够运行IE11。
Array[]
var listOfFiles=["fileList.txt”],
    cnt=0, 
    oReq = new XMLHttpRequest();

function reqListener () {
  if (listOfFiles[0]=="fileList.txt") {
    listOfFiles = this.responseText.split(",");
  }
  else { 
    processFile(this.responseText);
    cnt++;
  }
  getFile();
}

oReq.addEventListener("load", reqListener);
function getFile() { 
  if (cnt >= listOfFiles.length) return; 
  oReq.open("GET", listOfFiles[cnt]);
  oReq.send(); 
} 
getFile();
function getTOC() {
  var jsonStr = JSON.stringify({
    chapters: 2,
  });
  return Promise.resolve(jsonStr);
}

function getChapter(i) {
  return Promise.resolve("chapter " + i);
}

getTOC()
  .then(function(response) {
    var chapters = JSON.parse(response)["chapters"];
    return chapters;
  })
  .then(function(chapters) {
    var promises = [];
    for (i = 0; i < chapters; i++) {
      promises.push(getChapter(i));
    }
    return Promise.all(promises);
  })
  .then(function(results) {
    // results is an array of results, ordered as expected
    console.log(results);
  });