ES6 Promise对象概念与用法及案例分析

本文深入探讨Promise对象在异步编程中的应用,阐述其定义和作用,通过实例解析Promise的创建、then方法和catch方法的使用。同时,对比传统回调函数,展示Promise如何解决回调地狱问题,并通过读取多个文件的案例,逐步演示如何利用Promise优化异步操作,包括使用async/await进一步简化代码。
摘要由CSDN通过智能技术生成

一、Promise对象

定义

  • Promise是异步编程的一种解决方案,比传统的解决方案----回调函数和事件----更合理且更强大。所谓的Promise,简单来说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个一步操作)的结果。从语法上来说,promise是一个对象,从他可以获取异步操作的消息。Promise提供统一的API,各种异步操作都可以用同种的方法进行处理。有了Promise对象就可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。

作用

  • 有了Promise对象,就可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。此外,Promise对象提供统一的接口,使得控制异步操作更加容易

二、 Promise的使用

  • 生成promise对象,只需调用 Promise对象(),传入一个回调函数(resolve, reject) => {},这是用来让我们自定义什么时候发生状态的改变。
  • 调用then()方法,传入两个回调函数,他们是用来定义Promise分别变成两种不同状态时应该执行怎样的业务逻辑
  • 调用catch()方法,传入一个回调函数,定义当promise执行期间发生异常时应该执行怎样的业务逻辑,此时状态是reject。
  let promise = new Promise((resolve,reject)=>{
        console.log('11');
        //setTimeout是异步执行的,后面的代码不用等里面的回调函数执行完后再执行
        setTimeout(()=>{
            console.log('22);
            resolve('haha'); // 修改promise状态为 成功
        },0)
        console.log('33');
    });
    console.log('44');
    // 参数从resolve,reject中传入,第一个函数是定义resolve的回调函数,第二个是定义reject的回调函数
    
    // 定义成功或失败的具体执行方法
    promise.then((data)=>{
        //变成成功状态后自动执行
        console.log(`${data},成功了!`)
    },(error)=>{
        //变成失败状态后自动执行
        console.log(`${error},失败了!`);
    })
    // 当遇到异常或被reject时会调用
    promise.catch((error) => {
        console.log(`${error},异常了!`);
    })
    // 如果变成了reject状态拒绝(reject)和异常(catch)的方法都会被调用
    
    // finally则无论变成什么状态都会执行
     promise.finally(() => {
        console.log(`定型啦!`)
    })

在这里插入图片描述
总结:
从打印输出顺序可知道,Promise构造函数的同步阻塞式的,一调用,里面的代码就会执行。但是只是同步的代码会执行,异步的还是等最后再执行。

案例

读取a.txt文件,如果有内容,再读取b.txt文件,如果有内容,再读取c.txt文件,如果有内容,再读取d.txt文件

  • 异步方式读取文件
fs.readFile('./files/a.txt',function(err,a){
    if(!err){
        fs.readFile('./files/b.txt',function(err,b){
            if(!err){
                fs.readFile('./files/c.txt',function(err,c){
                    if(!err){
                        fs.readFile('./files/d.txt',function(err,d){
                            if(!err){
                                console.log('1.'+d.toString());
                            }
                        })
                    }
                })
            }
        })
    }   
})
// 注意观察上面的代码结构,层次非常深,特别不方便代理的阅读。我们将这样的代码结构称之为:回调地狱。

2.封装一个Promise对象,在里面读取第一个文件

new Promise(function(resolve,reject){
    // resolve,用于返回正确的结果
    // reject,用于返回错误信息
    fs.readFile('./files/a.txt',function(err,a){
        if(!err){
            resolve(a.toString())
        }
    })
})
.then(function(r){
    // 程序只能能进入到then,就表示之前的操作是成功,就要读取第二个文件;继续封装一个Promise对象,在里面读取第二个文件。
    return new Promise(function(resolve){
        fs.readFile('./files/b.txt',function(err,b){
            if(!err){
                resolve(b.toString())
            }
        })
    })
})
.then(function(r){
    return new Promise(function(resolve){
        fs.readFile('./files/c.txt',function(err,c){
            if(!err){
                resolve(c.toString())
            }
        })
    })
})
.then(function(r){
    return new Promise(function(resolve){
        fs.readFile('./files/d.txt',function(err,c){
            if(!err){
                resolve(c.toString())
            }
        })
    })
})
.then(function(r){
    console.log('2.'+r);
})

3.async关键字优化Promise对象

  • 使用async异步函数,配合await异步等待,继续简化Promise的过程。
async function run(){
    // 在异步函数中,通过await关键字获取,Promise对象里面的返回结果。
    // await关键字的作用是异步等待,必须等到有返回结果,程序才会继续往下执行。
    // await让异步代码,看上去像同步代码一样,其实本质上还是异步代码。
    // 注意:await关键字,只能在async函数中使用。
    await myRead('./files/a.txt')
    await myRead('./files/b.txt')
    await myRead('./files/c.txt')
    let d = await myRead('./files/d.txt')
    console.log('4.'+d);
}
run()

4.使用Promise编程,都会把公共的部分进行重新封装简写

new Promise(function(resolve,reject){
    // resolve,用于返回正确的结果
    // reject,用于返回错误信息
    fs.readFile('./files/a.txt',function(err,a){
        if(!err){
            resolve(a.toString())
        }
    })
})
.then(function(r){
    // 程序只能能进入到then,就表示之前的操作是成功,就要读取第二个文件;继续封装一个Promise对象,在里面读取第二个文件。
    return new Promise(function(resolve){
        fs.readFile('./files/b.txt',function(err,b){
            if(!err){
                resolve(b.toString())
            }
        })
    })
})
.then(function(r){
    return new Promise(function(resolve){
        fs.readFile('./files/c.txt',function(err,c){
            if(!err){
                resolve(c.toString())
            }
        })
    })
})
.then(function(r){
    return new Promise(function(resolve){
        fs.readFile('./files/d.txt',function(err,c){
            if(!err){
                resolve(c.toString())
            }
        })
    })
})
.then(function(r){
    console.log('2.'+r);
})
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值