Promise重学—基础知识

这是我参与更文挑战的第6天,活动详情查看: 更文挑战

Promise 是一门新的技术,是JS中进行异步编程的心解决方案,从语法上说,Promise是一个构造函数,从功能上来说,Promise对象用了封装一个异步操作并可以获取到其成功失败的结果值。

1, 常见的异步编程

1, fs 文件操作

require('fs').readFile('./index.html', (err, data) => {})
复制代码

2,数据库操作

3,AJAX

$.get('./server', (data) => {})
复制代码

4,定时器

setTimeout(() => {}, 200)
复制代码

2, Promise的特点

支持链式调用,可以解决回调地狱问题

(1) 文件的读取

// 以前读取文件的写法
const fs = require('fs')
fs.readFile('./package/content.txt',(err, data) => {
   // 如果错误,抛出错误
   if(err) throw err;
   //否则输出文件内容
   console.log(data.toString())
})

// 现在promise形式
let p = new Promise((resolve, reject) => {
   fs.readFile('./package/content.txt', (err, data) => {
      // 如果出错
       if(err) reject(err)
       // 如果成功
       resolve(data)
   })
})
// then里面有两个回调函数
p.then(value => {
   console.log(value.toString())
}, reason=> {
   console.log(reason)
})
复制代码

(2) Promise 封装 AJAX, 将用到一个开源 api地址:

api.apiopen.top/api.html

<!DOCTYPE html>
<html lang="en">
    <head>
        <title></title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <style>
            #page {
                font-size: 24px;
            }
            #btn {
                background-color: blue;
            }
        </style>
    </head>
    <body>
      <div class="container">
          <h2 class="page">Promise 封装AJAX操作</h2>
          <button class="btn" id="btn">点击发送</button>
      </div>
      <script>
           // 接口地址: https://api.apiopen.top/getJoke
           const btn = document.querySelector('#btn')
                 btn.addEventListener('click', function() {
                    // 创建Promise
                    const p = new Promise((resolve, reject) => {
                        const xhr = new XMLHttpRequest();
                            // 初始化
                            xhr.open('GET', 'https://api.apiopen.top/getJoke')
                            // 发送
                            xhr.send()
                            // 处理响应结果
                            xhr.onreadystatechange = function() {
                                if(xhr.readyState ===4) {
                                    // 判断响应状态码 2xx
                                    if(xhr.status >=200 && xhr.status < 300){
                                        // 成功,输出响应体
                                        // console.log(xhr.response)
                                        resolve(xhr.response)
                                    }else{
                                        // 失败
                                        //console.log(xhr.status)
                                        reject(xhr.status)
                                    }
                                }
                            }
                    });
                    p.then(value =>{
                       console.log(value)
                    }, reason => {
                        console.log(reason)
                    })
                 })
      </script>
    </body>
</html>
复制代码

当然也可以把AJAX的封装提取出来

function sendAjax(url) {
    return new Promise((resolve, reject) => {
        const xhr = new XMLHttpRequest()
        xhr.open('GET', url);
        xhr.send()
        xhr.onreadystatechange = function() {
            if(xhr.readyState === 4) {
                if(xhr.status >=200 && xhr.status < 300) {
                    resolve(xhr.response)
                } else {
                    reject(xhr.status)
                }
            }
        }
    })
}
复制代码

(3) 封装一个 读取文件的函数

/**
 * 封装一个函数 mineReadFile 读取文件内容
 * 参数: path  文件路径
 * 返回: promise 对象
 */
function mineReadFile(path) {
    return new Promise((resolve, reject) => {
        // 读取文件
        require('fs').readFile(path, (err, data) => {
            // 判断
            if(err) reject(err);
            // 成功
            resolve(data)
        })
    })
}
mineReadFile('./package/content.txt')
.then(value =>{
  console.log(value.toString())
},reason => {
  console.log(reason)
})
复制代码

也可以通过util.promisify():传入一个遵循常见的错误优先的回调风格的函数,并返回一个返回promise的版本

/**
 * util.promisify 方法
 */
//引入util模块
const util = require('util')
const fs = require('fs')
// 返回一个新函数
let mineReadFile = util.promisify(fs.readFile);
mineReadFile('./package/content.txt').then(value => {
    console.log(value.toString())
},reason => {
    console.log(reason)
})
复制代码

3, Promise 原理知识

(1)Promise的状态,实例对象中的一个属性:PromiseStatue, 一种有三只状态

  • pending 未决定的

  • resolved / fullfilled 成功

  • rejected. 失败

    状态的改变只能有两种情况,一个promise 对象只能改变一次

    1,pengding 变为resolved

    2, pending 变为 rejected

(2)Promise 对象的值, 实例对象中的一个属性: PromiseResult,保存异步任务成功/失败的结果

​ 1, resolve

​ 2, reject

4, Promise 的基本流程

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享