ES6学习笔记五(promise异步)

知识点1:rosolve是执行下一步then()

// Promise
{
    let ajax=function(){
        console.log('执行2');
        return new Promise(function(resolve,reject){
            setTimeout(function(){
                resolve()
            },1000);
        })
    }

    ajax().then(function(){
        console.log('promise','timeout2');
    })
}

知识点2:允许多个下一步(then()里面再嵌Promise实例)

{
    // 允许多个下一步
    let ajax=function(){
        console.log('执行3');
        return new Promise(function(resolve,reject){
            setTimeout(function(){
                resolve() //允许下一步then
            },1000);
        })
    }

    ajax()
       .then(function(){
        return new Promise(function(resolve,reject){
            setTimeout(function(){
                resolve();
            },2000);
        });
    })
       .then(function(){
           console.log('timeout3');
       })
}

知识点3:抛错时处理

{
    // 抛错时处理
    let ajax=function(num){
        console.log('执行4');
        return new Promise(function(resolve,reject){
            if(num>5){
                resolve()
            }else {
                throw new Error('出错了')
            }
        })
    }

    ajax(6).then(function(){
        console.log('log',6);
    }).catch(function(err){
        console.log('catch',err);
    });

    ajax(3).then(function(){
        console.log('log',3);
    }).catch(function(err){
        console.log('catch',err);
    });
}

应用场景:图片加载( Promise.all([]).then() 和  Promise.race([]).then() )

场景1:多张图片加载,实现所有图片加载完,再一起出现在页面上,提高用户体验

{

    // 所有图片加载完再添加到页面
    function loadImg(src){
        return new Promise((resolve,reject)=>{
            let img=document.createElement('img');
            img.src=src;
            img.onload=function(){
                resolve(img);
            }
            img.onerror=function(err){
                reject(err);
            }
        })
    }

    function showImgs(imgs){
        imgs.forEach(function(img){
            document.body.appendChild(img);
        })
    }

    Promise.all([  //all是把多个Promise实例,只有所有合成一个Promise实例,只有所有Promise实例状态都发生变化时,才会生成新的Promise实例
        loadImg('https://cdn.baigebao.com/upload/pc/20181016/5bc53a30b2291.png'),
        loadImg('https://cdn.baigebao.com/upload/pc/20181008/5bbad45787a22.png'),
        loadImg('https://cdn.baigebao.com/upload/pc/20181016/5bc53a30b2291.png')
    ]).then(showImgs);

}

场景2:有一个图片加载完成就添加到桌面

{
    // 有一个图片加载完成就添加到桌面
    function loadImg(src){
        return new Promise((resolve,reject)=>{
            let img=document.createElement('img');
            img.src=src;
            img.onload=function(){
                resolve(img);
            }
            img.onerror=function(err){
                reject(err);
            }
        })
    }

    function showImgs(img){
        let p=document.createElement('p');
        p.appendChild(img);
         document.body.appendChild(p);
    }

    Promise.race([  //只要有一个状态改变就先显示,只显示一张
        loadImg('https://cdn.baigebao.com/upload/pc/20181016/5bc53a30b2291.png'),
        loadImg('https://cdn.baigebao.com/upload/pc/20181008/5bbad45787a22.png'),
        loadImg('https://cdn.baigebao.com/upload/pc/20181016/5bc53a30b2291.png')
    ]).then(showImgs);

}

注意:

promise中的resolved 总是晚于本轮循环中的同步任务
例子:
new Promise((resolve, reject) => {
  resolve(1);
  console.log(2);
}).then(r => {
  console.log(r);
});
// 2
// 1

调用resolve(1)以后,后面的console.log(2)还是会执行,并且会首先打印出来。这是因为立即 resolved 的 Promise 是在本轮事件循环的末尾执行,总是晚于本轮循环的同步任务。

一般来说,调用resolve或reject以后,Promise 的使命就完成了,后继操作应该放到then方法里面,而不应该直接写在resolve或reject的后面。所以,最好在它们前面加上return语句,这样就不会有意外。

new Promise((resolve, reject) => {
  return resolve(1);
  // 后面的语句不会执行
  console.log(2);
})
 
原文地址:https://www.cnblogs.com/qdlhj/p/9935493.html