Rain120 / Web-Study

日常学习,工作写的笔记
66 stars 108 forks source link

限制异步操作并发数并尽可能快地完成 #32

Open Rain120 opened 2 years ago

Rain120 commented 2 years ago

同时下载的链接不超过 3 个的情况下,尽可能快地完成。

const urls = [
    {
        time: 1000,
        href: 'link1',
    },
    {
        time: 2000,
        href: 'link2',
    },
    {
        time: 3000,
        href: 'link3',
    },
    {
        time: 4000,
        href: 'link4',
    },
    {
        time: 3000,
        href: 'link5',
    },
    {
        time: 2000,
        href: 'link6',
    },
    {
        time: 1000,
        href: 'link7',
    },
    {
        time: 3000,
        href: 'link8',
    },
    {
        time: 1000,
        href: 'link9',
    },
    {
        time: 1000,
        href: 'link10',
    },
];

function loadImg(url) {
    return new Promise((resolve, reject) => {
        console.log('----' + url.href + 'start!');
        setTimeout(() => {
            console.log(url.href + 'ok!');
            resolve();
        }, url.time);
    });
}

function limitLoad(list, callback, limit) {
  // ...
}

limitLoad(urls, loadImg, 3);
Rain120 commented 2 years ago
function limitLoad(list, callback, limit) {
    const queue = list.slice();
    const promises = queue.splice(0, limit).map((url, index) => {
        return callback(url).then(() => {
            return index;
        });
    });

    let p = Promise.race(promises);

    queue.forEach((url, index) => {
        p = p.then((res) => {
            promises[res] = callback(url).then(() => {
                return res;
            });

            return Promise.race(promises);
        });
    });
}
Rain120 commented 2 years ago
const loadImg = (url, callback) => {
    return new Promise((resolve, reject) => {
        const img = new Image();

        img.onload = () => {
            resolve(img);
        }

        img.onerror = () => {
            reject(new Error('load error'));
        }

        img.src = url;
        callback(img);
    });
}