zoukankan      html  css  js  c++  java
  • 解读Es6之 promise

            单线程:  在同一时间只能有同一任务进行。JavaScript就是一门单线程语言
                    当有多个任务需要进行时,则需要进行排队,前一个执行完毕才能执行下一个;
                    当前一个任务报错后,则不进行下一个
            案例如下:
        // 1、同步
        function fun1(){
            console.log(1) 
            // throw Error("121212") // 错误时,则不向后进行
        }
        function fun2(){
            console.log(2)
        }
        function fun3(){
            console.log(3)
        }
        // fun1()
        // fun2()
        // fun3()
    
        /* 正确时输出
            1
            2
            3
    
           错误时输出
            解读promise.html:23 Uncaught Error: 121212
            at fun1 (解读promise.html:23)
            at 解读promise.html:31
        */
    View Code
    /*
          为什么要使用单线程语言?
                js是被设计在浏览器中使用的,浏览器多用于数据等的展示、更改等。 
    
                若有多个线程同时进行,如:
    
                数据1: “嘿嘿嘿,我是页面上的数据1,我的真实名字叫山本,我就是这么自信的数据” (页面数据)
                线程1: “二营长,你tm的意大利炮,给我干山本一炮” (对数据删除操作)
                线程2: “二营长,活捉山本”(对数据进行修改)
                浏览器:“身为二营长的我,太南了” (浏览器不知执行哪歩操作)
                
                这样,浏览器就会一脸闷逼。
    
                所以,js被设计为单线程,即可给山本一炮,干不死,再活捉!
    
                (最近独立团看多了,哈哈,简单比喻下吧)
        */ 
    View Code
    /*
            异步:即同时进行,当某个任务存在ajax等异步操作时,不必执行完才会执行下一个,如下
         */ 
    // 2、异步
        function fun4(){
            console.log(4)
        }
        function fun5(){
            setTimeout(()=>{
                console.log(5)
            },0)
        }
        function fun6(){
            console.log(6)
        }
        // fun4()
        // fun5()
        // fun6()
    
        /* 输出
            4
            6
            5
        */ 
    View Code
    /*
            异步编程,
            1、使用回调函数
            2、使用es6的promise ( 重点讲解 )
        */ 
    // Promise
    
        /*
            1、检查当前浏览器是否支持promise
                typeof(Promise)==="function"  
    
            2、三种状态
                pending(进行中)、fulfilled(已成功)和rejected(已失败)
    
            3、可以使异步操作变同步
    
    
        */ 
    
        /*
            基本使用:
            参数为js引擎自带
            resolve : 将pending状态转为 fulfilled状态
            reject :  将pending状态转为 rejected状态
        */ 
        let Promise_demo1 = new Promise((resolve, reject) => {
            let num = Math.floor( Math.random() * 10 )
            if (num > 5) { // 正确时 执行这个,并将参数传递出去
                resolve(num)
            } else { // 错误时,执行这个,可以支持任意参数
                reject(num + '错误了!')
            }
        })
    
        Promise_demo1
        .then( (data) => { // 表示 为成功状态时,要执行的,即通过 resolve 后执行
            // console.log(data)
        })
        .catch( (Error) => { // 表示 为失败状态时,要执行的,即通过 reject 后执行
            // console.log(Error)
        })
    
        // 以上通过 then catch ,也可只在then中执行,一个参数为成功时执行,第二个参数为失败时执行
        // Promise_demo1  
        // .then( (data) => {
        //     console.log(data)
        // }, (err) => {
        //     console.log(err)
        // } )
    
    
        // 通过函数使用promise
        function timeout(_time){
            let num = Math.floor( Math.random() * 10 )
            return new Promise( (resolve, reject) => {
                setTimeout(()=>{ resolve(num) },_time)
            } )
        }
    
        timeout(1000)
        .then( (data) => {
            // console.log(data) // 依次在1秒输出随机数 
        } )
        .catch( (err) => {} )
    
        /* 
            小插曲:
            Uncaught (in promise)
            期间,若报这个错,即reject发出错误,
            1、需要使用catch接收,即添加 .catch((e) => {})
            2、或,不使用reject返回错误
            为了严谨,推荐使用第一种
        */ 
    
        /*
            当既有promise执行,又有其他同步操作执行
            先 执行promise
            再 执行同步操作
            后 执行promise.then
            后 执行异步操作
            案例如下:
        */ 
    
        let Promise_demo2 = new Promise( (resolve, reject) => {
            // console.log("promise内支持的")
            resolve('promise成功后执行的')
        } )
    
        Promise_demo2
        .then( (data) => {
            // console.log(data)
        } )
    
        function func7(){
            // console.log('同步操作')
        }
        function func8(){
            setTimeout( ()=>{
                console.log("异步操作")
            },0 )
        }
    
        // func7()
        // func8()
        
        /* 输出
            promise内支持的
            同步操作
            promise成功后执行的
            异步操作
        */ 
    
        /*
            resolve, reject 不仅可以返回一个参数,还可以返回一个promise
            情况一: 参数的promise 的请求时间小于 调用者的promise请求时间
            以下输出:
            1秒后:Uncaught (in promise) 2121  ( 即先执行 .catch )
            3秒后:2121
    
            因为p1作为参数,在1秒后执行,p2在3秒后将p1作为参数传出去再执行
        */ 
    
        const p1 = new Promise(function (resolve, reject) {
            // setTimeout(() => reject('2121'), 1000)
        })
    
        const p2 = new Promise(function (resolve, reject) {
            // setTimeout(() => resolve(p1), 3000)
        })
    
        p2
        .then(result => console.log(result))
        .catch(error => console.log(error))
    
        /*
            情况二: 参数的promise 的请求时间 大于 调用者的promise请求时间
            以下输出:
            3秒后 Error: 错误了
    
            因为p4在1秒后状态改变,resolve返回的又是新的promise,导致p4的状态失效,p3的状态替换了p4的状态
        */ 
    
        const p3 = new Promise(function (resolve, reject) {
            // setTimeout(() => reject(new Error('错误了')), 3000)
        })
    
        const p4 = new Promise(function (resolve, reject) {
            // setTimeout(() => resolve(p3), 1000)
        })
    
        p4
        .then(result => console.log(result))
        .catch(error => console.log(error))
    
        /*
            .finally 不管是成功还是失败后,都会执行
        */ 
    
        let Promise_demo3 = new Promise( (resolve, reject) => {
            let num = Math.floor( Math.random() * 10 )
            if( num > 5 ) {
                // resolve('Oh Yeah')
            } else {
                // reject('Oh No')
            }
        } )
    
        Promise_demo3
        .then( data => console.log(data) )
        .catch( data => console.log(data) )
        .finally( () => console.log("I am finally") )  // 都会执行
    
    
        /*
            Promise.all()
            用于将多个Promise实例,包装成一个promise实例
            如 let p_all = Promise.all( [ promise1, promise2, promise3 ] );
            
            当所有参数返回resolve时, promise.all则返回resolve
            当有一个参数返回reject时,promise.all则返回reject
    
            如下:
        */ 
    
        let arrImg = ['img/0.jpg', 'img/1.jpg', 'img/2.jpg'];
        function loadImg(url){
            return new Promise( (resolve, reject) => {
                let img = new Image();
                // img.src = url;
                // img.onload = () => resolve(img); // 或 resolve(this)
                // img.onerror = () => reject('加载失败');
            } )
        }
        
        let PromiseAll = Promise.all( [ loadImg(arrImg[0]), loadImg(arrImg[1]), loadImg(arrImg[2]) ] )
        // 若将其中的一个改为不存在的路径时,则会报错 如将loadImg(arrImg[0])改为  loadImg(arrImg[3]),
        PromiseAll
        .then( images => {
            // images.forEach(value => document.body.appendChild(value))
        } )
        .catch( data => console.log(data,'错误时提示') )
        .finally( () => console.log('程序运行完成') )
        
    
        /*
            Promise.race() 参数均为promise
            const p = Promise.race([p1, p2, p3]);        
            当其中一个参数的状态改变时,p的状态就会改变
        */ 
    
    
        /*
            Es2020 新加  Promise.allSettled() 
            const p_allSe = Promise.allSettled([p1, p2, p3]);  
            可能部分浏览器暂时不支持,
            使用场景:不关心异步操作的结果,只关心这些操作有没有结束 
        */ 
    
            // let p_allSe = Promise.allSettled([p3, p4])
            // p_allSe.then( result => console.log( result ) )
    
    
    
        /*
            Promise.resolve()
            将现有对象转为 Promise 对象
    
            不知实际项目中能解决什么问题,有大神知道的可以回复下
        */ 
    
    
        /*
            Promise.reject()
        */ 
    
        // let p_reject = Promise.reject(new Error('12121'))
        // p_reject.catch((err)=> console.log(err)) // 报出错误来
    
        /*
            Promise.try()
        */ 
    
        // 将两个或多个含有异步操作的函数 同步执行
    
        function func9(){
            return new Promise( resolve => {
                setTimeout(() => {
                    console.log(9)
                    resolve()
                },1000)
            } )
        }
        function func10(){
            console.log(10)
        }
        func9().then( ()=>func10() )
    
        // 
        function func9(){
            setTimeout(() => {
                console.log(9)
            },1000)
        }
        function func10(){
            console.log(10)
        }
    
        
    View Code
  • 相关阅读:
    Java 编程基础
    LING 实战
    C# 3.0\3.5 新特性
    EF Code First 入门
    C# 4.0 新特性
    JavaScript学习(二)
    JavaScript学习(一)
    csdn的blog后台程序的导航菜单的实现
    HashTable的遍历
    开通啦
  • 原文地址:https://www.cnblogs.com/-roc/p/12039877.html
Copyright © 2011-2022 走看看