ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

斗胆谈谈Promise

2021-11-26 22:33:53  阅读:176  来源: 互联网

标签:斗胆 resolve console new 谈谈 Promise reject promise


1.Promise概念

1.1为什么需要promise?

promise是ES6异步编程新的解决方案,它可以用来解决回调地狱的问题,回调地狱就是许多回调函数嵌套,导致代码太乱了,不易读,也不太好看。如下代码(读文件是异步操作,需要回调函数不停嵌套,透露出一股恶心劲)

fs.readFile('./1.html',(err,data)=>{
    if(err) throw err;
    fs.readFile('./2.html',(err,data1)=>{
        if(err) throw err;
        fs.readFile('./3.html',(err,data2)=>{
            if(err) throw err;
            fs.readFile('./4.html',)
        })
    })

})

1.2promise是什么?

promise其实就是一个构造函数,它里面包含一些属性和方法,支持链式调用。

promise其中一个属性PromiseState代表它的状态,它只有三种状态:

fulfilled/resolved(成功)

rejected (失败)

pending (进行中,最初的状态)

其中只会有两种情况的状态变化:

pending -> fulfilled/resolved

pending->rejected

就是只能从初始变为成功,或者从初始变为失败,成功和失败之间不能再互相转化了。

下面我们通过具体的使用来了解。

2.Promise使用

2.1创建promise

上代码(最简单的promise使用,定义一个成功的promise)

let p = new Promise((resolve,reject)=>{
            resolve('ok')
        })
console.log(p);

输出P是一个promise实例,它的状态是成功的,PromiseResult是promise的另一个属性,代表promise的值。

定义一个失败的promise

let p = new Promise((resolve,reject)=>{
            reject('fail')
        })
 console.log(p);

 输出结果是P是一个promise但他的状态是rejected失败的,promise的值就是传入的值

 2.2promise的方法

then():

then方法的参数可以传入两个回调函数,当promise状态变为成功( fulfilled)时,执行第一个参数接受的回调函数,状态变为失败(rejected)执行第二个参数接收的回调函数,注意then方法返回的仍然是一个promise对象,所以在then方法之后可以继续调用then方法

上代码

let p = new Promise((resolve,reject)=>{
            reject('fail')
        })
        p.then((value)=>{
            console.log('成功',value);
        },(reason)=>{
            console.log('失败',reason);

        })

当一个rejected状态的promise调用.then时执行的是第二个参数的回调函数,所以输出失败,值就是通过reject()传入的值

 let p = new Promise((resolve,reject)=>{
            resolve('ok')
           
        })
        p.then((value)=>{
            console.log('成功',value);
        },(reason)=>{
            console.log('失败',reason);

        })
        

 同理,当一个resolve状态的promise调用.then时,执行的是第一个参数的回调函数,输出成功,value值就是通过resolve()传入的值

 那我们说then返回的也是一个promise对象,若then里面的回调函数返回的是非promise的数值那么then返回的就是resolved/fulfilled状态的promise,

如果then里面的回调函数返回的是promise类型,则回调函数返回的promise的成功与否直接决定了then方法返回的promise的结果和状态(有些绕,看代码就清楚了)

上代码(回调函数返回非promise)

let p = new Promise((resolve,reject)=>{
            resolve('ok')
           
        })
        const res = p.then((value)=>{
            console.log('成功',value);
        },(reason)=>{
            console.log('失败',reason);})
            
        console.log(res);
p是resolved状态的,那么执行then里面的第一个回调函数,打印成功,回调函数并没有返回一个新的promise,因此p.then返回的就是一个状态为fulfilled的promise,值为undifined,因为没有新的promise对象。

 回调函数返回promise

 let p = new Promise((resolve,reject)=>{
            resolve('ok')
           
        })
        const res = p.then((value)=>{
            return new Promise((resolve,reject)=>{
                resolve('new Promise')

            })  
        },(reason)=>{
            console.log('失败',reason);})

        console.log(res);

因为成功的回调函数返回了一个新的promise,他决定了then返回的promise的状态和值也是成功的,值就是传入的新值

let p = new Promise((resolve,reject)=>{
            resolve('ok')
           
        })
        const res = p.then((value)=>{
            return new Promise((resolve,reject)=>{
                reject('fail Promise')

            })  
        },(reason)=>{
            console.log('失败',reason);})

        console.log(res);

 

若回调函数返回的是失败的promise,则then返回的也是失败的promise,值就是传入的值

catch()

promise还有一个特点是可以进行异常穿透,就是已经失败了,就不要总是定义失败(reject)的回调函数了,只要在最后指定一个失败的回调catch()就好了,捕获失败结果,返回值就第一个失败的值,这样代码就更清晰了。

 let p1 = new Promise((resolve,reject)=>{
            reject('fail')
           
        })
        p1.then((value)=>{
            console.log('成功',value);

        }).catch(e=>
            {
            console.log('失败',e);
        })

失败的promis执行catch(),then方法里面不用再写失败的回调了

 如果.then后面还有.then,许许多多.then也不怕,catch仍然能抓到第一个失败的值

 let p1 = new Promise((resolve,reject)=>{
            resolve('ok')
           
        })
        p1.then(value=>{
            console.log('111');
            

        }).then(value=>{
            console.log('222');
            throw('ERROR')
        }).then(value=>{
            console.log('333');
            
        }).catch(reason=>{
            console.log('失败',reason)
        })

成功的promise会继续执行.then方法,直到catch捕获到了第一个失败,就不再继续执行了,不会输出33333

 all()

promise.all传入的是一个promise类型的数组,它的返回值也是一个promise,他的状态由数组决定,若promise数组里均为resolved状态的,那么promise.all返回的就是resolved状态的,值就是由所有传入值组成的数组,若promise数组中有一个失败了,那么promise.all返回的就是reject状态的,值就是失败的传入的值

上代码(promise全为成功状态)

let p1 = new Promise((resolve,reject)=>{
            resolve('ok')
           
        })
        let p2 = new Promise((resolve,reject)=>{
            resolve('success')
           
        })
        let p3 = new Promise((resolve,reject)=>{
            resolve('nice')
           
        })
        const res = Promise.all([p1,p2,p3])

        console.log(res);

有一个为失败状态

  let p1 = new Promise((resolve,reject)=>{
            resolve('ok')
           
        })
        let p2 = new Promise((resolve,reject)=>{
            reject('fail')
           
        })
        let p3 = new Promise((resolve,reject)=>{
            resolve('nice')
           
        })
        const res = Promise.all([p1,p2,p3])

        console.log(res);

 race()

promise.all传入的也是一个primise数组,返回值是一个promise,只是它的状态和值是由最先发生变化的promise状态和值决定的,就像赛跑先到先得

        let p1 = new Promise((resolve,reject)=>{
            resolve('ok')
           
        })
        let p2 = new Promise((resolve,reject)=>{
            reject('fail')
           
        })
        let p3 = new Promise((resolve,reject)=>{
            resolve('nice')
           
        })
        const res = Promise.race([p1,p2,p3])

        console.log(res);

 P1先到,是成功的,值是ok,则all方法返回的promise是成功的值为ok

若P1变为异步了,则p2先到那么结果一定会是一个返回失败的promise

        let p1 = new Promise((resolve,reject)=>{
            setTimeout(()=>{
                resolve('ok')
            })
        })
        let p2 = new Promise((resolve,reject)=>{
            reject('fail')
           
        })
        let p3 = new Promise((resolve,reject)=>{
            resolve('nice')
           
        })
        const res = Promise.race([p1,p2,p3])

        console.log(res);

4.async await

async是一个函数,返回结果是一个promise对象

1.如果函数里面return的不是一个promise,那promise的结果就是成功的,值就是return的数值

2.如果函数里面return的是一个promise,那async的Promise就是return的promise

3.抛出异常,返回的就是失败的promise对象

(这个很像对于then方法那个表述)

await右边表达式一般为promise对象

1.右边是promise对象,await返回值是promise成功值

2.右边是其他值,直接将此值作为await的返回值(很少用)

注意二者常常结合使用简化promise操作

await必须写在async里面,但是async可以没有await

上代码

        async function main(){
            let p = new Promise((resolve,reject)=>{
                resolve('ok')
                // reject('error')
            })
            try{
                let res = await p;
                console.log(res);
            }catch(e){
                console.log(e);
            }
            
        }
        main()

await返回的是promise的成功值,所以需要用try catch捕获失败的情况,输出ok,以后就可以用这样的方法简化promise操作,只需要awaitpromise成功的值即可

标签:斗胆,resolve,console,new,谈谈,Promise,reject,promise
来源: https://blog.csdn.net/weixin_43946748/article/details/121568393

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有