Promise串行输出小练习

328 阅读1分钟

每隔1秒分别打印1、2、3

// 第一种
function printNums(nums) {
  let p = Promise.resolve();
  for (let i = 0; i < nums.length; i++) {
    p = p.then(() => {
      return new Promise((resolve) => {
        setTimeout(() => {
          console.log(nums[i]);
          resolve();
        }, 1000);
      });
    });
  }
}

// 第二种
function printNums(nums) {
  nums.reduce((promise, num) => {
    return promise.then(() => {
      return new Promise((resolve) => {
        setTimeout(() => {
          console.log(num);
          resolve();
        }, 1000);
      });
    });
  }, Promise.resolve());
}

限制异步操作的并发个数并尽可能快的完成全部

思路:例如一开始最多并发3个异步操作,每个异步操作返回一个promise,在promise.then处理程序中,判断是否还有请求要发起,是则发起一个新请求,否则判断请求是否全部返回,是则resolve

// 该方法为加载图片,可忽略不看
function loadImg(url) {
    return new Promise((resolve, reject) => {
        let img = document.createElement("img")
        img.src = url
        img.onload = () => {
            console.log("某张图片加载完成")
            resolve()
        }
        img.onerror = () => {
            console.log(url + "图片加载失败了!")
        }
    })
}
// 限制并发数加载
function limitLoad(urls, limit = 3) {
   let data = []
   let imgs = urls.slice()
   return new Promise((resolve, reject) => {
       while(limit) {
           limit --
           createAPromise(imgs, data, resolve)
       }
   })
}
// 发起一个异步请求
/**
 * @param {Array} imgs: 所有图片地址 
 * @param {Array} data: 完成请求的图片数组 
 * @param {Function} resolve: 所有请求完成后, limitLoad的promise要更改状态为fulfilled
 * @returns 默认返回Promise.resolve(undefined)
 */
function createAPromise(imgs, data, resolve) {
    return loadImg(imgs.shift()).then((res) => {
        data.push(res);
        if(imgs.length) {
            createAPromise(imgs, data, resolve)
        }
        if(data.length === imgs.length) {
            resolve()
        }
    })
}

可以看到,最初只加载了3张图片,并在每一个图片加载完后,继续判断还有没有图片可以继续加载。

image.png

参考霖呆呆还有评论大佬的