1.图片加载
Question:
实现图片的依次加载和并行加载
// 封装加载图片的promise
let loadImg = (src)=>{
return new Promise((resolve, reject)=>{
let img = new Image();
img.onload = ()=>{
resolve(img);
}
img.onerror = ()=>{
reject(new Error());
}
})
}
const imgs = ['url1', 'url2', 'url3'];
// 依次加载图片
async function fSync(){
for (let i=0,len=imgs.length; i<len; i++){
let img = await loadImg(imgs[i]);
document.body.appendChild(img);
}
}
// 并行加载图片
function fAsync(){
imgs.forEach(async item=>{
let img = await loadImg(imgs[i]);
document.body.appendChild(img);
})
}
2. Promise原生实现
Question:
原生实现promise,实现依次调用,eg:a().then()
两种实现思路
思路一:利用异步,后置resove和reject的执行
function MyPromise(fn){
// promise内部状态
this.status = 'pending';
fn(this.resolveWrap.bind(this), this.rejectWrap.bind(this));
}
MyPromise.prototype.resolveWrap = function(res){
if (this.status != 'pending'){
return;
}
let that = this;
setTimeout(function(){
that.resolve(res);
that.status = 'fulfilled';
}, 0)
}
MyPromise.prototype.rejectWrap = function(res){
if (this.status != 'pending'){
return;
}
let that = this;
setTimeout(function(){
that.reject(res);
that.status = 'rejected';
}, 0)
}
// 实现then方法
MyPromise.prototype.then = function(resolve, reject){
this.resolve = resolve || function(){};
this.reject = reject || function(){};
}
// 测试MyPromise
var loadImg = function(){
return new MyPromise((resolve, reject)=>{
let img = new Image();
img.onload = function(){
resolve(img);
reject(new Error('图片加载失败'));
}
img.onerror = function(){
reject(new Error('图片加载失败'));
}
img.src = "http://p1.meituan.net/movie/7a2c3acb1bda2baad8df309b046d0872344909.jpg@160w_220h_1e_1c";
})
}
loadImg().then(res=>{
document.body.appendChild(res);
});
思路二:先保存resolve和reject执行时传递的参数,then方法里实际执行
function MyPromise(executor){
let self = this;
self.status = 'pending';
self.value = undefined;
self.reason = undefined;
function resolve(value) {
if(self.status === 'pending') {
self.status = 'resolved';
self.value = value;
}
}
function reject(reason) {
if (self.status === 'pending'){
self.status = 'rejected';
self.reason = reason;
}
}
try {
excutor(resolve, reject);
}catch(e) {
reject(e);
}
}
MyPromise.prototype.then = function(onFulfilled, onRejected){
let self = this;
if (self.status === 'resolved'){
onFulfilled(self.value);
}
if (self.status === 'rejected'){
onRejected(self.reason);
}
}
// 测试MyPromise
var loadImg = function(){
return new MyPromise((resolve, reject)=>{
let img = new Image();
img.onload = function(){
resolve(img);
reject(new Error('图片加载失败'));
}
img.onerror = function(){
reject(new Error('图片加载失败'));
}
img.src = "http://p1.meituan.net/movie/7a2c3acb1bda2baad8df309b046d0872344909.jpg@160w_220h_1e_1c";
})
}
loadImg().then(res=>{
document.body.appendChild(res);
});