javascript 处理多个回调互斥量

javascript handling multiple callback mutexes

我是 javascript 的新手。假设我有以下代码。

let sources =["http://localhost:3001/resources/black_bish",""http://localhost:3001/resources/white_bish""]
let loaded_images=0
sources.forEach(ele = > {
    let img = new Image()
    img.src = ele
    img.onload = function () {
        loaded_images=++
    }
})

这里我有一个关于Javascript和并发的问题。不能像使用线程时那样同时调用 2 个回调吗?在这里,不会有竞争条件吗?如果我要执行与 "loaded_images=++" 不同的操作,是否存在任何我应该担心的竞争条件(例如操纵数据结构)?

谢谢

一种方法是为您加载的每个图像 return 一个 Promise。这个 promise 将 resolve,或者用外行的话来说:只要图像已经加载,当满足正确的条件时继续。它就像一个 return 语句,但不是结束函数,而是继续下一步。

Promise.all 是 promise 构造函数上的一个方法,它接受一个 promise 数组。当数组中的所有承诺都已 fullfilled (意味着 resolve 已被调用)然后对所有承诺的值做一些事情。

const loadImage = (source) => new Promise(resolve => {
  let img = new Image();
  img.onload = function() {
    resolve(img);
  };
  img.src = source;
});

const whenAllImagesAreLoaded = (...sources) => Promise.all(
  sources.map(source => loadImage(source));
);

whenAllImagesAreLoaded('image-1.jpg', 'image-2.jpg').then((images) => {
  images.forEach(image => {
    console.log(image, ' is loaded');
  });
});

另一个例子也是将 promise 与 async / await 语法结合使用,它会停止执行,直到您正在等待的 promise 已经实现。

这打开了可能性,例如:在加载上一张图像后,一个接一个地加载图像。

async function loadImagesSequentially(...sources) {
  for (const source of sources) {
    let image = await loadImage(source);
    console.log(image, ' is loaded');
  }
}

这两种方法都可以让您更好地控制如何处理竞争条件,或者完全消除它们。我建议你尽可能多地练习承诺。它是您 JavaScript 工具箱中非常强大的工具。

如果您有任何问题,请告诉我。