使 .each() 等待将元素转换为 DataURL

make .each() wait for converting element to DataURL

我正在使用 html2canvas 转换 html2canvas,

我正在使用 .each 解析 html,然后将元素传递给 html2canvas。元素转换为 DataURL 后。我将它推送到数组 content

$('.itinerary-section-detail').each(function( index, element ) { 
                 setTimeout(function() {
                   console.log(element);
                       html2canvas(element).then(function(canvas) {
                            element.appendChild(canvas);
                             elem  = canvas.toDataURL();
                              var item = {};
                              item["image"] = elem;
                              item["width"] = 595;
                              content.push(item);
                          }); 
                  }, 4000);
            });

但问题是将元素转换为 DataURL 的时间会有所不同。这就是为什么元素的顺序是随机的。所以我需要等到一个元素被转换为 DataURL,将其推入 content 数组,然后来自 .each.

的下一个元素

请在这里给我一个方法。试过 setTimeout,没用。

您不能只循环遍历异步元素,因为它们不会暂停循环。相反,您可以构建承诺数组并使用 $.when。然后,一旦所有承诺都解决,您提供的回调将被调用:

var promises = $('.itinerary-section-detail').map(function(index, element) {
  console.log(element)
  return html2canvas(element).then(function(canvas) {
      element.appendChild(canvas)
      var elem = canvas.toDataURL()

      return {
        image: elem,
        width: 595
      }
    })
}).get()

$.when.apply(null, promises).then(function() {
  var content = [].slice.call(arguments)
  console.log(content)
})

这显示了我在评论中所说的内容。我用超时和随机延迟模拟了异步。

在示例中,IIFE 仅用于跟踪 index 因为它会在异步回调中丢失(您也可以将异步调用包装在存储值的函数中)

results finish 没有排序,但是数组结果是。

var content = [];

$('div.kadd').each(function( index, element ) { 
    console.log('launching: ' + element.innerHTML);
    (function(i){ setTimeout(function() {
        console.log('finishing: ' + element.innerHTML);
        content[i] = element.innerHTML;
    }, (Math.random() * 100) + 1); })(index);
});

setTimeout(function() {
    console.log('result: ', content);
}, 1000);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div class="kadd">A</div>
<div class="kadd">B</div>
<div class="kadd">C</div>
<div class="kadd">D</div>
<div class="kadd">E</div>
<div class="kadd">F</div>
<div class="kadd">G</div>