美文网首页
es6学习笔记整理(十三)Promise异步

es6学习笔记整理(十三)Promise异步

作者: 尤樊容 | 来源:发表于2018-03-13 11:44 被阅读12次
    什么是异步?

    函数传递过去不会立即执行,而是等着请求成功之后才能执行。对于这种传递过去不执行,等出来结果之后再执行的函数,叫做callback,即回调函数.
    实现异步的最核心原理,就是将callback作为参数传递给异步执行函数,当有结果返回之后再触发 callback执行

    Promise的作用

    用回调的方式去实现异步,在多次调用的时候写法将非常复杂,而且影响了后期维护,而promise可以简单解决。
    它最大的作用就是解决了异步回调函数层层嵌套的问题

    Promise的基本用法

    前后台通信ajax模拟,下面是普通的回调实现

    let ajax = function (callback) {
        console.log('执行');
        setTimeout(function () {
            callback&&callback.call();//判断回调是否存在
        },1000);
    };
    
    ajax(function(){
        console.log('time1');//一秒以后显示 time1
    });
    

    使用promise实现

    let ajax = function () {
        console.log('执行2');
        //resolve执行下一步操作,reject中断操作
        return new Promise(function (resolve, reject){
            setTimeout(function () {
                resolve();
            },1000);
        });
    };
    
    ajax().then(function(){
        console.log('time2');//一秒以后显示 time2
    },function(){});
    

    使用promise实现连续的链式操作

    let ajax = function () {
        console.log('执行3');
        //resolve执行下一步操作,reject中断操作
        return new Promise(function (resolve, reject){
            setTimeout(function () {
                resolve();
            },1000);
        });
    };
    
    ajax().then(function(){
        return new Promise(function(resolve, reject){
            setTimeout(function () {
                resolve();
            },2000);
        });
    }).then(function(){
        console.log('time3');
    });
    

    链式操作过程中,如果有一步出错,使用catch捕获错误

    let ajax = function (num){
        console.log('执行4');
        return new Promise(function (resolve, reject){
            if(num>5){
                resolve();
            }else{
                throw new Error('错误');
            }
        });
    };
    
    ajax(2).then(function (){
        console.log('succcess');
    }).catch(function (err){
        console.log(err);
    });
    
    Promise.all和Promise.race

    以加载多张图片为例,了解Promise.all和Promise.race
    Promise.all把多个Promise实例当做一个Promise实例,所有图片加载完成以后才会触发Promise.all这个新的对象, 所以Promise.all对象then方法,也就是Promise.all方法返回的是一个Promise实例, 所以才可以调用then方法

    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([   loadImg('https://ad.12306.cn/res/delivery/0001/2018/03/12/201803121538379477.jpg'),     loadImg('https://ad.12306.cn/res/delivery/0002/2018/03/12/201803121543172067.jpg'),     loadImg('https://ad.12306.cn/res/delivery/0002/2018/03/12/201803121543172067.jpg')
    ]).then(showImgs);
    

    Promise.race与Promise.all相反
    有一个图加载完就显示到界面,哪个优先返回就先显示哪个,其他忽略不管

    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://ad.12306.cn/res/delivery/0001/2018/03/12/201803121538379477.jpg'),
        loadImg('https://ad.12306.cn/res/delivery/0002/2018/03/12/201803121543172067.jpg'),
        loadImg('https://ad.12306.cn/res/delivery/0002/2018/03/12/201803121543172067.jpg')
    ]).then(showImgs);
    

    相关文章

      网友评论

          本文标题:es6学习笔记整理(十三)Promise异步

          本文链接:https://www.haomeiwen.com/subject/oxfofftx.html