【ECMAScript6】Promise

Promise介绍与基本使用

Promise 是 ES6 引入的异步编程的新解决方案。语法上 Promise 是一个构造函数,用来封装异步操作并可以获取其成功或失败的结果。

        const p = new Promise(function(resolve, reject) {
            setTimeout(() => {
                // let successData = '数据库中的用户数据'
                // resolve(successData)
                let failData = '数据读取失败'
                reject(failData)
            }, 1000);
        })

        p.then(function(value) {
            console.log('@success' + value)
        }, function(error) {
            console.error('@fail' + error)
        })

Promise封装读取文件

在这里插入图片描述

        // 1. 引入fs模块
        const fs = require('fs')
        
        // 2. 调用方法读取file1文件
        fs.readFile('./file1.md', (err, data) => {
            // 若失败,则抛出错误
            if(err) throw err
            // 如果没有失败,则输出文件内容
            console.log(data.toString())  // 我是file11111
        })
        
        // 3. 使用Promise封装
        const p = new Promise(function(resolve, reject){
            fs.readFile('./file1.md1', (err, data) => {
                // 若失败,则抛出错误
                if(err) reject(err)
                // 如果没有失败,则输出文件内容
                resolve(data)
            })
        })
        
        p.then(function(value){
            console.log(value.toString())
        }, function(error){
            console.error(error)
        })

Promise封装Ajax请求

        // 假设接口地址为:https://api.apiopen.top/getJoke
        
        // 原生ajax请求
        // 1. 创建对象
        const xhr = new XMLHttpRequest()
        
        // 2. 初始化
        xhr.open('GET', 'https://api.apiopen.top/getJoke')
        
        // 3. 发送
        xhr.send()
        
        // 4. 绑定事件,处理响应结果
        xhr.onreadystatechange = function() {
            if(xhr.readyState === 4) {
                if(xhr.status >= 200 && xhr.status < 300) {
                    console.log(xhr.response)
                }else {
                    console.error(xhr.status)
                }
            }
        }
        

        // 通过Promise封装后的ajax请求
        const p = new Promise(function(resolve, rejece) {
            const xhr = new XMLHttpRequest()
            xhr.open('GET', 'https://api.apiopen.top/getJoke')
            xhr.send()
            xhr.onreadystatechange = function() {
                if(xhr.readyState === 4) {
                    if(xhr.status >= 200 && xhr.status < 300) {
                        resolve(xhr.response)
                    }else {
                        rejects(xhr.status)
                    }
                }
            }
        })
        
        p.then(function(value) {
            console.log(value)
        }, function(error) {
            console.error(error)
        })  

通过Promise封装ajax的好处:数据请求和数据处理解耦合,不用在数据请求之后直接处理数据,而是通过then函数来处理,有效解决回调地狱。

Promise对象的then方法

        const p = new Promise((resolve, reject) => {
            setTimeout(() => {
                resolve('请求数据成功')
            }, 1000)
        })
        // 一个Promise实例对象有三个状态,分别是初始化、成功和失败
        
        const result = p.then(value => {
            console.log(value)
        }, error => {
            console.log(error)
        })

        console.log(result) // Promise实例对象调用then方法后返回的也是一个Promise

Promise实例对象调用then方法后的Promise对象状态由什么决定?
该状态由回调函数的执行结果决定:

  1. 如果回调函数中的返回结果是 非Promise类型的类型,则状态为成功,返回值为对象成功的值
  2. 如果回调函数中的返回结果是 Promise对象,则它的状态和返回值中Promise的状态一致
    • 若返回结果中的Promise状态为成功,则调用then之后的Promise对象状态为成功,并且成功的值也一致
    • 若返回结果中的Promise状态为失败,则调用then之后的Promise对象状态为失败,并且失败的值也一致
    • 若返回结果中的Promise抛出错误,则它的状态为失败,并且调用then之后的Promise对象状态也为失败
        const p = new Promise((resolve, reject) => {
            setTimeout(() => {
                resolve('请求数据成功')
            }, 1000)
        })

        const result = p.then(value => {
            console.log(value)
            // return 123
            return new Promise((resolve, reject) => {
                // resolve('ok')
                // reject('error')
                throw new Error('出错')
            })
        }, error => {
            console.log(error)
        })

        console.log(result)

        // 由于then方法的特性,所以then方法是可以链式调用的,链式调用可以解决回调地狱问题
        p.then(value => {}, error => {}).then(value => {}, error => {})

Promise应用实例:多个文件内容读取

在这里插入图片描述

  1. 回调地狱的写法
        const fs = require('fs')
        fs.readFile('./file1.md', (err, data1) => {
            fs.readFile('./file2.md', (err, data2) => {
                fs.readFile('./file3.md', (err, data3) => {
                    let result = data1 + '\r\n' + data2 + '\r\n' + data3 
                    console.log(result)
                })
            })
        })
  1. Promise实现
        const p = new Promise((resolve, reject) => {
            fs.readFile('./file1.md', (err, data) => {
                resolve(data)
            })
        })
        
        p.then(value => {
            return new Promise((resolve, reject) => {
                fs.readFile('./file2.md', (err, data) => {
                    resolve([value, data])
                })
            })
        }).then(value => {
            return new Promise((resolve, reject) => {
                fs.readFile('./file3.md', (err, data) => {
                    value.push(data)
                    resolve(value)
                })
            })
        }).then(value => {
            console.log(value.join('\r\n'))
        })

在这里插入图片描述

Promise对象的catch方法

        const p = new Promise((resolve, reject) => {
            setTimeout(() => {
                reject('出错了')
            }, 1000)
        })
        p.catch(error => {
            console.log(error)
        })

通过Promise对象上的catch方法可以直接捕捉到错误信息,而不用通过then方法的第二个参数

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值