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

Javascript make.each()等待将元素转换为DataURL,javascript,jquery,promise,html2canvas,Javascript,Jquery,Promise,Html2canvas,我正在使用html2canvas转换html2canvas 我正在使用解析html。每个,然后将元素传递给html2canvas。元素转换为DataURL后。我将它推送到一个数组content $('.itinerary-section-detail').each(function( index, element ) { setTimeout(function() { console.log(element);

我正在使用
html2canvas
转换html2canvas

我正在使用
解析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
数组,然后从
进入下一个元素


请给我指路。已尝试设置超时,但无效。

不能在异步元素上循环,因为它们不会暂停循环。相反,您可以构建承诺数组并使用。然后,在所有承诺解决后,将调用您提供的回调:

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

您不能在异步元素上循环,因为它们不会暂停循环。相反,您可以构建承诺数组并使用。然后,在所有承诺解决后,将调用您提供的回调:

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仅用于跟踪
索引
,因为它将在异步回调中丢失(您也可以将异步调用包装到存储值的函数中)

结果完成未排序,但数组结果为

var content=[];
$('div.kadd')。每个(函数(索引,元素){
log('launching:'+element.innerHTML);
(函数(i){setTimeout(函数(){
log('finishing:'+element.innerHTML);
content[i]=element.innerHTML;
},(Math.random()*100)+1);}(索引);
});
setTimeout(函数(){
console.log('result:',content);
}, 1000);

A.
B
C
D
E
F

这显示了我在评论中说的话。我用一个超时和一个随机延迟来模拟异步

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

结果完成未排序,但数组结果为

var content=[];
$('div.kadd')。每个(函数(索引,元素){
log('launching:'+element.innerHTML);
(函数(i){setTimeout(函数(){
log('finishing:'+element.innerHTML);
content[i]=element.innerHTML;
},(Math.random()*100)+1);}(索引);
});
setTimeout(函数(){
console.log('result:',content);
}, 1000);

A.
B
C
D
E
F


G
似乎
.toDataURL()
是同步的,您可以做的是为每次异步启动增加一个变量(
html2canvas
我猜),并将其传递给回调,以便元素知道它必须放在数组中的哪个索引中不尝试说它,我实际上是在说它;)加上一个例子我认为昨天没用?@JaromandaX这和昨天不一样。这是关于
。每个
及其内部都将元素转换为
DataURL
和元素排序问题似乎
.toDataURL()
是同步的。您可以做的是为每次异步启动增加一个变量(
html2canvas
),并将其传递给回调,这样元素就可以知道它必须放在数组中的哪个索引中。我不是在说它,而是在说它;)加上一个例子我认为昨天没用?@JaromandaX这和昨天不一样。这是关于
。每个
及其内部都将元素转换为
数据URL
,元素排序问题谢谢您的回答,我如何将返回的对象推送到
$中的
内容
数组。何时
?很抱歉问这个问题,我不知道这一切仍然得到与
console.log('done',arguments)相同的结果我的意思是我在问题中发布的
var item={};项目[“图像”]=元素;项目[“宽度”]=595;内容推送(项目);我怎样才能在
$中做到这一点。当我得到
ZoneAwarePromise的数组时,你不需要推送任何东西,内容数组将在我在回答中发布的回调中可用。
内容
数组显示
[ZoneAwarePromise,ZoneAwarePromise,ZoneAwarePromise,ZoneAwarePromise,ZoneAwarePromise]
我需要
[{image:elem1,width:595},{image:elem2,width:595},{image:elem3,width:595}]
,我怎么能得到这个呢?谢谢你的回答,我怎么能把返回的对象推到
$中的
内容
数组中呢?当
的时候?很抱歉这个问题,我没有意识到这一切仍然得到与
控制台.log('done',arguments)相同的结果
我的意思是我在问题中发布的
var item={};item[“image”]=elem;item[“width”]=595;content.push(item);我怎样才能在
$中做到这一点。当我得到
ZoneAwarePromise的数组时,你不需要推送任何东西,内容数组将在我在回答中发布的回调中可用。
内容
数组显示
[ZoneAwarePromise,ZoneAwarePromise,ZoneAwarePromise,ZoneAwarePromise]
我需要
[{image:elem1,width:595},{image:elem2,width:595},{image:elem3,width:595}]
,我怎么能得到这个?谢谢你的回答,我不能添加
setTimeout()
因为可能有太多的元素。这是一个我更喜欢的函数,所以需要对所有人执行相同的操作,并且使用
setTimeout
将花费太多时间setTimeout只是一个异步示例,在您的情况下,您只需将其替换为
html2canvas()
。我的示例确实缺少知道所有异步调用都已结束的代码(这可以通过承诺完成,我使用了全局超时)。顺便说一句,承诺本身并不保证结果将按顺序到达,这就是我回答的目的,