浅析Promise

124 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第9天,点击查看活动详情

什么是Promise?

promise是ES6引入的,对于异步编程的一种新的解决方案。

promise本质是一个回调函数,支持链式调用,是为了解决回调地狱的问题。

举个例子:

function rand(m, n) {
    return Math.ceil(Math.random() * (n - m + 1)) + m - 1
}

const p = new Promise((resolve, reject) => {
    setTimeout(() => {
        const n = rand(1, 100)
        n <= 30
            ? resolve(n) // 将promise对象的状态设置为成功
            : reject(n) // 将promise对象的状态设置为失败
    }, 1000);
})

p.then((value) => {
    console.log('成功,输出的数字是' + value)
}, (reason) => {
    console.log('失败!,输出的数字是' + reason)
})

这里p是一个Promise对象,通过then方法来输出结果。

使用Promise发送Ajax请求

  • 使用原生Ajax发送请求
<script>
    btn.onclick = function () {
        // 1.创建化对象
        const xhr = new XMLHttpRequest()
        // 2.初始化
        xhr.open('GET', 'https://api.apiopen.top/api/sentences')
        // 3.发送
        xhr.send()
        // 4.处理响应结果
        xhr.onreadystatechange = function () {
            if (xhr.readyState == 4) {
                // 判断响应状态码
                if (xhr.status >= 200 && xhr.status < 300)  console.log(xhr.response) //输出响应体
                else console.log(xhr.status) //输出状态码
            }
        }
    }
</script>
  • 使用promise发送请求
<script>
    btn.onclick = function () {
        const p = new Promise((resolve, reject) => {
            // 1.创建化对象
            const xhr = new XMLHttpRequest()
            // 2.初始化
            xhr.open('GET', 'https://api.apiopen.top/api/sentences')
            // 3.发送
            xhr.send()
            // 4.处理响应结果
            xhr.onreadystatechange = function () {
                if (xhr.readyState == 4) {
                    // 判断响应状态码
                    xhr.status >= 200 && xhr.status < 300
                        ? resolve(xhr.response)
                        : reject(xhr.status)
                }
            }
        })
        p.then((value) => {
            console.log(value)
        }, (response) => {
            console.log(response)
        })
    }
</script>

在node.js中使用Promise

  • 回调形式

image.png

  • promise形式

image.png

Promise 状态

Promise实例对象中的一个属性:PromiseState,有三个属性:

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

Promise流程

image.png

Promise的API

catch

传递一个参数,返回错误原因。 image.png

resolve

resolve方法是属于Promise函数的,不是属于实例的。

image.png

image.png

如果传入的参数非Promise对象,则返回状态成功的Promise对象。 如果传入的参数是Promise对象,则参数的结果决定了resolve的结果

reject

属于Promise函数。无论传入什么,都返回错误

image.png

all

属于Promise函数。

包含n个Promise实例对象的数组,返回一个新的Promise对象,只有所有的promise都成功才返回成功的结果,有一个失败,就返回失败的结果。

image.png

image.png

race

属于Promise函数。

包含n个Promise实例对象的数组,返回一个新的Promise对象,第一个完成的Promise结果状态就是最终的结果状态。

image.png

image.png

async

async函数的返回值为promise对象,该对象的结果由async函数执行的返回值决定。

  • 函数没有返回值,则返回的promise对象状态为成功,值是undefined。

image.png

  • 函数返回值是一个非promise对象,则返回的promise对象状态为成功,值是async函数的返回值。

image.png

  • 函数的返回值是一个promise对象,则返回的promise对象的状态和值都要看async函数的返回值。

image.png

async和await封装Ajax请求

<button id="btn">CLICK</button>
<script>
    function sendAJAX(url) {
        return new Promise((resolve, reject) => {
            // 1.创建化对象
            const xhr = new XMLHttpRequest()
            xhr.responseType = 'json'
            // 2.初始化
            xhr.open('GET', url)
            // 3.发送
            xhr.send()
            // 4.处理响应结果
            xhr.onreadystatechange = function () {
                if (xhr.readyState == 4) {
                    // 判断响应状态码
                    xhr.status >= 200 && xhr.status < 300
                        ? resolve(xhr.response)
                        : reject(xhr.status)
                }
            }
        })
    }
    btn.onclick = async function () {
        const p = await sendAJAX('https://api.apiopen.top/api/sentences')
        console.log(p)
        console.log(p.result.name)
    }
</script>

async与await

在async的await后面跟一个返回异常/错误/错误状态的Promise的函数,都会终止代程序执行,可以利用这种特性,不对返回错误的结果进行判断,只顺序书写返回正确结果的代码。要想不影响程序的执行,可以使用try-catch捕获。

image.png

在这里addPermission()当里面返回一个错误状态的Promise时,程序就不会向下执行。

image.png