Promise的理解和使用

92 阅读1分钟

这是我参与【第四届青训营】笔记创作活动的第3天。

1.1. Promise 是什么?

1.1.1. 理解

  1. 抽象表达: 1) Promise 是一门新的技术(ES6 规范) 2) Promise 是 JS 中进行异步编程的新解决方案 备注:旧方案是单纯使用回调函数
  2. 具体表达:
  3. 从语法上来说: Promise 是一个构造函数
  4. 从功能上来说: promise 对象用来封装一个异步操作并可以获取其成功/ 失败的结果值

1.1.2. promise 的状态改变

  1. pending 变为 resolved
  2. pending 变为 rejected

Promise的状态

实例对象中的一个属性 【PromiseState】

pending 未决定的 resolve / fullfilled 成功 rejected 失败

  1. 说明: 只有这 2 种, 且一个 promise 对象只能改变一次 无论变为成功还是失败, 都会有一个结果数据 成功的结果数据一般称为 value, 失败的结果数据一般称为 reason

    Promise对象的值

    实例对象中的另一个属性 【PromiseResult】

    保存着异步任务【成功/失败】 的结果

    resolve rejected

1.1.3. promise 的基本流程

1.1.4. promise 的基本使用

  1. 使用 1: 基本编码流程

    <script>
    // 1) 创建 promise 对象(pending 状态), 指定执行器函数
    const p = new Promise((resolve, reject) => {
    // 2) 在执行器函数中启动异步任务
    setTimeout(() => {
    const time = Date.now()
    // 3) 根据结果做不同处理
    // 3.1) 如果成功了, 调用 resolve(), 指定成功的 value, 变为 resolved 状if (time%2===1) {
    resolve('成功的值 '+ time)
    } else { // 3.2) 如果失败了, 调用 reject(), 指定失败的 reason, 变为
    rejected 状态
    reject('失败的值' + time)
    }
    }, 2000)
    })
    // 4) 能 promise 指定成功或失败的回调函数来获取成功的 vlaue 或失败的 reason
    p.then(
    value => { // 成功的回调函数 onResolved, 得到成功的 vlaue
    console.log('成功的 value: ', value)
    },
    reason => { // 失败的回调函数 onRejected, 得到失败的 reason
    console.log('失败的 reason: ', reason)
    }
    )
    </script>
    
  2. 使用 2: 使用 promise 封装基于定时器的异步

    <script>
    function doDelay(time) {
    // 1. 创建 promise 对象
    return new Promise((resolve, reject) => {
    // 2. 启动异步任务
    console.log('启动异步任务')
    setTimeout(() => {
    console.log('延迟任务开始执行...')
    const time = Date.now() // 假设: 时间为奇数代表成功, 为偶数代表失败
    if (time %2=== 1) { // 成功了
    // 3. 1. 如果成功了, 调用 resolve()并传入成功的 value
    resolve('成功的数据 ' + time)
    } else { // 失败了
    // 3.2. 如果失败了, 调用 reject()并传入失败的 reason
    reject('失败的数据 ' + time)
    }
    }, time)
    })
    }
    const promise = doDelay(2000)
    promise.then(
    value => {
    console.log('成功的 value: ', value)
    },
    reason => {
    console.log('失败的 reason: ', reason)
    },
    )
    </script>
    
  1. 使用 3: 使用 promise 封装 ajax 异步请求

    <script>
    /*
    可复用的发 ajax 请求的函数: xhr + promise
    */
    function promiseAjax(url) {
    return new Promise((resolve, reject) => {
    const xhr = new XMLHttpRequest()
    xhr.onreadystatechange = () => {
    if (xhr.readyState!==4) return
    const {status, response} = xhr
    // 请求成功, 调用 resolve(value)
    if (status>=200 && status<300) {
    resolve(JSON.parse(response))
    } else { // 请求失败, 调用 reject(reason)
    reject(new Error('请求失败: status: ' + status))
    }
    }
    xhr.open("GET", url)
    xhr.send()
    })
    }
    promiseAjax('https://api.apiopen.top2/getJoke?page=1&count=2&type=vid
    eo')
    .then(
    data => {
    console.log('显示成功数据', data)
    },
    error => {
    alert(error.message)
    }
    )
    </script>