每隔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张图片,并在每一个图片加载完后,继续判断还有没有图片可以继续加载。