Я работаю на C ++ и изучаю javascript. Уроки Mozilla по webgl имеют код, подобный приведенному ниже (реальный код и ссылка внизу). Я пытаюсь понять, почему код в функции обратного вызова «onload» всегда будет выполняться. Мне кажется, что экземпляр объекта Image должен быть мусором в коде ниже. Таким образом, теоретически он может быть собран мусором до завершения загрузки и вызывает обратный вызов onload.
function foo()
{
image = new Image();
image.onload = function()
{
/*stuff to do when image gets done loading */
Console.log(image.width);
}
image.src = url;
}
Единственная идея, которая у меня есть, заключается в том, что функция, использующая «image.width» - объект функции должен хранить экземпляр изображения в памяти. Но это будет ссылка на круг, потому что эта функция существует только на самом объекте изображения; Единственная ссылка на объект функции AFAIK - это свойство обратного вызова onload. Поэтому круговая ссылка (image-> onload-> function-> image-> ...) должна быть собрана мусором.
Кажется, я чего-то не понимаю, или между загрузкой изображения и его сборкой мусора возникает гонка.
JS Ссылка, показывающая круговые эталонные острова, которые более недоступны, должна собираться мусором. https://javascript.info/garbage-collection
Учебное пособие Ссылка:
https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/Tutorial/Using_textures_in_WebGL
function loadTexture(gl, url) {
const texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture);
// Put a single pixel in the texture until it loads
const level = 0; const internalFormat = gl.RGBA; const width = 1; const height = 1; const border = 0; const srcFormat = gl.RGBA; const srcType = gl.UNSIGNED_BYTE; const pixel = new Uint8Array([0, 0, 255, 255]); // opaque blue
gl.texImage2D(gl.TEXTURE_2D, level, internalFormat,width, height, border, srcFormat, srcType, pixel);
const image = new Image();
image.onload = function() {
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.texImage2D(gl.TEXTURE_2D, level, internalFormat,srcFormat, srcType, image);
// WebGL1 has different requirements for power of 2 images vs non power of 2 images so check if the image is a power of 2 in both dimensions.
if (isPowerOf2(image.width) && isPowerOf2(image.height)) {
gl.generateMipmap(gl.TEXTURE_2D); // Yes, it's a power of 2. Generate mips.
} else {
// No, it's not a power of 2. Turn off mips and set wrapping to clamp to edge
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
}
};
image.src = url;
return texture;
}
//irrelevant, but including for completeness
function isPowerOf2(value)
{
return (value & (value - 1)) == 0
}