Javascript 创建多个画布模式失败

Javascript 创建多个画布模式失败,javascript,jquery,canvas,chart.js,Javascript,Jquery,Canvas,Chart.js,我正在尝试创建一个用于我的甜甜圈图表的模式数组,因此我执行以下操作: var surfacePatterns var surfaceNames = ['Unknown', 'Paved', 'Unpaved', 'Concrete', 'Cobblestone', 'Metal', 'Wood', 'Ground', 'Sand', 'Grass'] $(document).ready(() => { surfacePatterns = [] console.lo

我正在尝试创建一个用于我的甜甜圈图表的模式数组,因此我执行以下操作:

var surfacePatterns
var surfaceNames = ['Unknown', 'Paved', 'Unpaved', 'Concrete', 'Cobblestone', 'Metal', 'Wood', 'Ground', 'Sand', 'Grass']

$(document).ready(() => {    
    surfacePatterns = []
    console.log(surfacePatterns)
    for (i = 0; i < surfaceNames.length; i++) {
        var temp = new Image()
        temp.onload = () => surfacePatterns.push($("#canvas1")[0].getContext('2d').createPattern(temp, 'repeat'))
        temp.src = '../img/surfaces/'+ surfaceNames[i] + '.jpg'
    }
});

function chart(){
   console.log(surfacePatterns)
}


整个数组完全为空(=/=null)。另外,将数组初始化为空数组后的第一个日志会给我一个长度为9的空数组,我不知道为什么,因为还没有发生其他任何事情。

在“for”中多次调用异步函数时,您必须等待所有调用。如果不等待,则会丢失一些异步调用,并得到一个空数组

如果你能帮我解决这个问题

window.surfacePatterns=[];
窗口c=0;
//window.surfaceNames=[‘未知’、‘已铺’、‘未铺’、‘混凝土’、‘鹅卵石’、‘金属’、‘木材’、‘地面’、‘沙子’、‘草’];
window.surfaceNames=[”https://www.worldatlas.com/r/w1200-h630-c1200x630/upload/37/99/85/northern-pygmy-owl.jpg",
"https://www.friendsofwehr.org/wp-content/uploads/2013/06/Great-horned_Owl_RWD_at_CRC1transparent.jpg"
];
$(文档).ready(()=>{
console.log('Step 1:',window.surfacePatterns);
对于(i=0;i

您需要等待加载所有模式,然后才能记录阵列。事实上,数组应该是等待所有模式的结果,而不是异步填充外部范围中的变量。看

至于如何解决这个问题,您可以在将每个回调转换为挂起的承诺后使用:

const surfaceNames=['stackoverflow.com'、'codegolf.stackexchange.com'、'superuser.com'、'codereview.stackexchange.com'];
const context=document.querySelector('#canvas1').getContext('2d');
const promises=surfaceName.map(surfaceName=>
新承诺((解决、拒绝)=>{
常量图像=新图像();
image.addEventListener('load',()=>{
解析(context.createPattern(图像“repeat”);
});
image.addEventListener('error',()=>{
拒绝(新错误(${surfaceName}未能加载${image.src}');
});
image.src=`https://${surfaceName}/favicon.ico`;
}).catch(错误=>{
//使用空条目填充数组并记录错误
//而不是忽视所有其他悬而未决的承诺
console.log(错误消息);
返回null;
})
);
承诺。所有(承诺)。然后(surfacePatterns=>{
log(surfacePatterns.map(pattern=>pattern.constructor.name));
});

如上所述,即使我在调用图表之前等待一分钟左右,结果也是一样的。或者你的意思是,如果我启动下一个异步调用,它将删除之前的一个?for的运行速度比异步调用(方法onload)快。您使用哪种框架?你曾经使用过承诺吗?没有框架。我不使用承诺-在这种情况下它们将如何使用?测试:如果不使用
surfacePatterns.push
而使用
控制台。log
是否获得所有9种模式?这是一种非常聪明的方法!我还学习了'String${variable}String'——这也很棒。谢谢@MiXT4PE,该语法称为自ECMAScript 2015以来可用的
temp.onload = () => surfacePatterns.push($("#canvas1")[0].getContext('2d').createPattern(temp, 'repeat'))
temp.onload = () => surfacePatterns[i] = canvas1[0].getContext('2d').createPattern(temp, 'repeat')