Joj*_*oji 5 html javascript es6-promise
我有一个图像 url 数组,我想按照数组中相应 URL 的放置顺序在网页上显示这些图像。
例如,我们有
const imgUrls = [
"https://picsum.photos/400/400",
"https://picsum.photos/200/200",
"https://picsum.photos/300/300"
];
Run Code Online (Sandbox Code Playgroud)
在这种情况下,我们希望显示400/400first、then200/200和last 300/300。
如果我们天真地实现它,那么顺序就无法保证。
function loadImages(imgUrls, root) {
imgUrls.forEach((url) => {
const image = document.createElement("img");
image.onload = () => {
root.append(image);
};
image.src = url;
});
}
Run Code Online (Sandbox Code Playgroud)
所以我使用 Promises 来管理异步流程控制
async function loadImagesInOrder(imgUrls, rootEl) {
const promises = imgUrls.map(
(url) =>
new Promise((resolve, reject) => {
const image = document.createElement("img");
image.onload = resolve;
image.onerror = reject;
image.src = url;
})
);
for (const p of promises) {
const { currentTarget } = await p;
rootEl.append(currentTarget);
}
}
Run Code Online (Sandbox Code Playgroud)
它有效,但并非总是有效。通过这种实现,有时null您最终会null在网页上看到一些图像。
这是现场演示 https://codesandbox.io/s/load-images-in-order-t16hs?file=/src/index.js
有人能指出问题是什么吗?还有没有更好的方法来确保图像按照数组中 URL 的顺序出现在页面上?
看起来.currentTarget事件的发生有时是null出于某种原因。一个简单的解决方法是使用图像本身来解决 Promise,而不是通过有问题的load处理程序。基思在评论中找到了原因:
注意:event.currentTarget 的值仅在处理事件时可用
但当你这样做时
for (const p of promises) {
const { currentTarget } = await p;
rootEl.append(currentTarget);
}
Run Code Online (Sandbox Code Playgroud)
所有图像都会立即启动加载过程,但它们加载是异步的,并且通常不按顺序加载。如果 Promise 在图像加载后解析,则该图像将.currentTarget不存在 - 例如,如果加载图像 1,然后加载图像 3,然后加载图像 2,则在第三个图像加载时,图像 3 已经加载完毕
const { currentTarget } = await p;
Run Code Online (Sandbox Code Playgroud)
运行。
如果您最终只需要正确排序图像,更简单的方法是立即附加它们。
for (const p of promises) {
const { currentTarget } = await p;
rootEl.append(currentTarget);
}
Run Code Online (Sandbox Code Playgroud)
const { currentTarget } = await p;
Run Code Online (Sandbox Code Playgroud)