我遇到一个问题,即循环的de index顺序在回调中不断变化。请参阅下面的代码,了解我尝试过的内容,我要实现的目标是根据可用图层添加标记。但是,我在图层上循环的顺序必须与添加标记的顺序相同。稍后,当我解决此问题时,目标是用户可以单击生成的标记,这将导致打开信息的图层。有谁知道解决方案是什么?我已经尝试了@patrickRoberts和@stian的评论。
$(function(){
// I've tried the following:
// – async/await with promises
// – JavaScript Closures
// – Closures with IIFE (see example below)
'use strict';
//Cache DOM
let $win = $(window),
$doc = $(document),
$body = $('body'),
$layer = $('.layer'),
$drawingImage = $('.drawings__image'),
$markerContainer = $('.markers');
//Init
_addMarkers();
function _addMarkers(){
for(var i = 0; i < $layer.length; i++){
//Right order
console.log(i);
(function(i){
_calculateScaleFactor($drawingImage.eq(0), function(data){
//Wrong order
console.log(i);
});
})(i);
}
}
function _createMarker(x, y, ){
return $(`<span class="markers__single-marker" style="left:${x}px; top:${y}px;">${i}</span>`);
}
function _calculateScaleFactor(image, callback){
let newImage = new Image();
newImage.src = image.attr('src');
newImage.onload = function(){
let scaleFactor = newImage.width / image.width();
callback(scaleFactor);
}
}
})
答案 0 :(得分:0)
经过几个小时的实验(根本没有等待/异步经验)我终于用async和await修复了它。特别感谢@stian!希望解决方案也能帮助他人,请参阅下面的代码:
$(function(){
'use strict';
//Cache DOM
let $win = $(window),
$doc = $(document),
$body = $('body'),
$layer = $('.layer'),
$drawingImage = $('.drawings__image'),
$markerContainer = $('.markers');
//Init
_addMarkers();
async function _addMarkers(){
for(var i = 0; i < $layer.length; i++){
let _self = $layer.eq(i),
layerData = {
x: _self.data('x'),
y: _self.data('y')
}
await _calculateScaleFactor($drawingImage.eq(0)).then(function(resolve){
layerData.x = (layerData.x / resolve) + $drawingImage.eq(0).offset().left;
layerData.y = (layerData.y / resolve) + $drawingImage.eq(0).offset().top;
$markerContainer.append( _createMarker(layerData.x, layerData.y, i) );
console.log(i);
});
}
}
function _createMarker(x, y, i){
return $(`<span class="markers__single-marker" style="left:${x}px; top:${y}px;">${i}</span>`);
}
function _calculateScaleFactor(image){
return new Promise(function(resolve, reject){
let newImage = new Image();
newImage.src = image.attr('src');
newImage.onload = function(){
let scaleFactor = newImage.width / image.width();
resolve(scaleFactor);
}
});
}
})
答案 1 :(得分:-1)
使用async / await和promises可以做到这一点。希望它有用。
$(() => {
//your array of elements
let arr = ["hello", "hi", "bye"]
calculate(arr)
})
async function calculate(arr){
for(let i = 0; i < arr.length; i++){
console.log(i, arr[i])
let result = await someAsyncStuff(arr[i])
console.log(i, result)
}
}
function someAsyncStuff(el){
return new Promise((resolve, reject) => {
//your async code here
setTimeout(resolve, 2000, el)
})
}