繁体   English   中英

数组被覆盖

[英]Array gets overwritten

背景:我有一个函数,该函数接收本地链接字符串数组,加载每个链接,并从每个链接中的特定位置查找所有<a>标记,然后将每个标记的href属性推入名为results的数组中。

问题:函数完成运行后,结果数组为空。 如果我使用.load()函数中的console.log测试数组的长度或内容,则该数组具有我所期望的内容; 但是,该函数之外的数组为空。

假设:我认为填充的数组在某种程度上被空数组所覆盖,但是我看不到这是怎么回事。 我什至尝试将结果数组作为全局变量放置在主函数之外,但在函数执行后仍然为空。

功能

function collectAllTrailLinks(arrayOfSections){
   var result = [];
   var len = arrayOfSections.length;
   $("body").append("<div id='placeHolder'></div>");

   for (var i = 0; i < len; i++) {
      var params = arrayOfSections[i] + " " + "blockquote a";
      $("#placeHolder").load(params, function(){
        $("#placeHolder a").each(function(){
            var link = $(this).attr("href");
            if (link !== "symbols.html") {
                result.push(link);
            }
         });
     }); 
   }
   console.log(result.length);
   //return result;
}

函数调用

function ctRunAll(){
  createTable("#ctSection h1", 16);
  var sectionLinks = collectLinks(hikingContent);
  collectAllTrailLinks(sectionLinks[0]);
}

这是因为传递给$("#placeHolder").load()的回调函数是异步执行的。 这意味着在第一次调用该回调之前,函数collectAllTrailLinks()已经完成。

您可以做的就是返回承诺,这样您就可以等待所有负载完成。 我创建了一个代码片段,以演示本地Promise方式(用setTimeout代替$.load简化了)

 var output = document.getElementById('output'); function collectAllTrailLinks() { var promises = []; for (var i = 0; i < 20; i++) { var promise = new Promise(function(resolve, reject) { var index = i; setTimeout(function() { output.innerHTML += 'finished ' + index + ' '; resolve('result of ' + index); }, i * 200); }); promises.push(promise); } return Promise.all(promises); } collectAllTrailLinks().then(function (result) { output.innerHTML += '<br /><br />All done: ' + JSON.stringify(result); }); 
 <div id="output"></div> 

jQuery延迟方式

function collectAllTrailLinks(arrayOfSections) {
   var defer = $.Deferred();
   var result = [];
   var len = arrayOfSections.length;
   var finishedLoads = 0;
   $("body").append("<div id='placeHolder'></div>");

   for (var i = 0; i < len; i++) {
      var params = arrayOfSections[i] + " " + "blockquote a";
      $("#placeHolder").load(params, function(){
        $("#placeHolder a").each(function(){
            var link = $(this).attr("href");
            if (link !== "symbols.html") {
                result.push(link);
            }
         });
         finishedLoads++;
         if (finishedLoads == len) {
             defer.done(result); // mark deferred as done (will resolve promise)
         }
     }); 
   }
   return defer.promise(); // return promise where you can wait on
}

// Usage (wait for promise)
collectAllTrailLinks(arrayOfSections).done(function(result) {
   console.log(result.length);
});

本机承诺方式

function collectAllTrailLinks(arrayOfSections) {
   var promises = [];

   $("body").append("<div id='placeHolder'></div>");

   for (var i = 0; i < arrayOfSections.length; i++) {
       var promise = new Promise(function(resolve, reject) {
          var params = arrayOfSections[i] + " " + "blockquote a";
          $("#placeHolder").load(params, function(response, status, xhr) {
             if (status === "error") {
                 return reject(response);
             }

             var result = [];
             $("#placeHolder a").each(function() {
                var link = $(this).attr("href");
                if (link !== "symbols.html") {
                   result.push(link);
                }
             });

             resolve(result);
          });
       });
       promises.push(promise);
   }

   return Promise.all(promises);
}

// Usage
collectAllTrailLinks(arrayOfSections).then(function(results) {
   console.log(results.length);
});

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM