图片最多同时加载X张的处理方案
var urls = [
'https://www.999code.com/path/1.jpg',
'https://www.999code.com/path/2.jpg',
'https://www.999code.com/path/3.jpg',
'https://www.999code.com/path/4.jpg',
'https://www.999code.com/path/5.jpg',
'https://www.999code.com/path/6.jpg',
'https://www.999code.com/path/7.jpg',
'https://www.999code.com/path/8.jpg',
'https://www.999code.com/path/9.jpg',
'https://www.999code.com/path/10.jpg',
];
function loadImg(url) {
return new Promise((resolve, reject) => {
const img = new Image();
img.onload = function() {
console.log("一张图片加载完成");
resolve(img);
};
img.onerror = function() {
reject(new Error('Could not load image at' + url));
};
img.src = url;
});
function limitLoad(urls, handler, limit) {
let sequence = [].concat(urls); // 复制urls
// 这一步是为了初始化 promises 这个"容器"
let promises = sequence.splice(0, limit).map((url, index) => {
return handler(url).then(() => {
// 返回下标是为了知道数组中是哪一项最先完成
return index;
});
});
// 注意这里要将整个变量过程返回,这样得到的就是一个Promise,可以在外面链式调用
return sequence
.reduce((pCollect, url) => {
return pCollect
.then(() => {
return Promise.race(promises); // 返回已经完成的下标
})
.then(fastestIndex => { // 获取到已经完成的下标
// 将"容器"内已经完成的那一项替换
promises[fastestIndex] = handler(url).then(
() => {
return fastestIndex; // 要继续将这个下标返回,以便下一次变量 返回值并没有什么其他的价值但是handler处理过程有意义
}
);
})
.catch(err => {
console.error(err);
});
}, Promise.resolve()) // 初始化传入
.then(() => { // 最后三个用.all来调用
return Promise.all(promises);
});
}
limitLoad(urls, loadImg, 3)
.then(res => {
console.log("图片全部加载完毕");
console.log(res);
})
.catch(err => {
console.error(err);
});
使用Promise实现红绿灯交替重复亮
红灯3秒亮一次,黄灯2秒亮一次,绿灯1秒亮一次;如何让三个灯不断交替重复亮灯?
要求:用Promise实现
三个亮灯函数已经存在:
const d = new Date() * 1
function red() {
console.log(new Date() * 1 - d)
console.log("red");
}
function green() {
console.log(new Date() * 1 - d)
console.log("green");
}
function yellow() {
console.log(new Date() * 1 - d)
console.log("yellow");
}
function light(timer, cb) {
return new Promise((resolve, reject) => {
setTimeout(() => {
cb()
resolve()
}, timer)
})
}
function step() {
Promise.resolve().then(() => {
return light(3000, red)
}).then(() => {
return light(2000, green)
}).then(() => {
return light(1000, yellow)
}).then(() => {
step()
})
}
step()
// light(3000,red)
实现mergePromise函数
把传进去的数组按顺序先后执行,并且把返回的数据先后放到数组data中。
const time = (timer) => {
return new Promise(resolve => {
setTimeout(() => {
resolve()
}, timer)
})
}
const ajax1 = () => time(2000).then(() => {
console.log(1);
return 1
})
const ajax2 = () => time(1000).then(() => {
console.log(2);
return 2
})
const ajax3 = () => time(1000).then(() => {
console.log(3);
return 3
})
mergePromise([ajax1, ajax2, ajax3]).then(data => {
console.log("done");
console.log(data); // data 为 [1, 2, 3]
});
// 要求分别输出
// 1
// 2
// 3
// done
// [1, 2, 3]
function mergePromise(ajaxArray){
const data=[]
let promise=Promise.resolve()
ajaxArray.forEach(ajax => {
promise=promise.then(ajax).then(res=>{
data.push(res)
return data
})
});
return promise
}