ES6 —- Promise

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

介绍

Promise 是ES6对异步编程一种解决方案。Promise就是一个对象容器,将异步操作(同步也可以但是没有必要这么做)保存在容器内部,当异步操作执行时就可以Promise获取当前异步操作的消息。这种模式会比传统回调更强大与合理。

Promise 异步操作有三种状态:pending(进行中)、fulfilled(已成功)和 rejected(已失败)。除了异步操作的结果,任何其他操作都无法改变这个状态。

Promise 对象只有:从 pending 变为 fulfilled 和从 pending 变为 rejected 的状态改变。只要处于 fulfilledrejected ,状态就不会再变了即 resolved(已定型)

基本用法

概念 Promise就是一个构造函数用来生成Promise实例对象

语法 Promise构造函数在生成实例对象时接收一个函数作为参数,该函数接收两个参数(由js引擎所提供)

  • 参数一 resolve 是一个函数它的作用是将Promise 的状态由 pending变为fulfilled (resolve),是一个异步操作执行成功时需要调用的方法

  • 参数二 reject 是一个函数它的作用是将Promise 的状态由 pending变为reject,是一个异步操作执行失败时需要调用的方法

以上两个参数都可以将自身接收的参数传递出去

let p = new Promise(function (resolve, reject{
    let num = Math.random()

    if (num > 0.5) {
        resolve(num) // 成功调用resolve方法,将num传递出去else {
        reject('失败了!'// 失败调用reject方法,将'失败了!'传递出去
    }
})
复制代码

prototype.then

概念 Promise实例对象生成完毕后可以使用分别制定resolve状态和reject状态的回调函数

语法 then 方法接收两个函数作为参数

  • 参数一 Promise 执行成功时的回调函数,接收resolve传递的参数

  • 参数二 Promise 执行失败时的回调 接收reject传递的参数

两个函数只会有一个被调用。

let p = new Promise(function (resolve, reject{
    let num = Math.random()

    if (num > 0.5) {
        resolve(num) // 成功调用resolve方法else {
        reject('失败了!'// 调用reject方法
    }
})
       
p.then(
    res => console.log('成功!' + res), // resolve 的回调函数
    err => console.error(err) // reject的回调函数
)
复制代码

prototype.catch

概念 Promise实例对象生成完毕后,当状态 从 pending转换为reject状态时,then方法第二个参数的别名。reject抛出的异常会被catch所捕获

语法

p.then(
    res => console.log('成功!' + res), // resolve 的回调函数
    err => console.error(err) // reject的回调函数
)
// 就可以改写为
p.then(res => console.log('成功!' + res) // resolve 的回调函数
    .catch(err => console.error(err)) // reject的回调函数
复制代码

prototype.finally

概念 在promise结束时,无论结果是fulfilled或者是rejected,都会执行指定的回调函数。一般做一些异步请求的清理工作。

语法

p.finally(() => console.log('异步操作执行完毕,无论成功失败') )

p.then(function(json) { })
  .catch(function(error) { })
  .finally(function() { });
复制代码

all

概念 该方法接收多个 promise对象并返回一个 promise对象。多个的 promise 都执行成功后调用promise对象方法

注意 所有的promise都成时 all的状态也是成功;如果有一个Promise失败 all的状态也是失败,失败的原因是第一个失败 promise 的结果。

语法

 function fakeAjax(timeout, name , isSuccess = true{
    return new Promise((resolve, reject) => {

        setTimeout(() => {
            if(isSuccess) {
                resolve(name)
            }else {
                reject(name)
            }
        }, timeout)

    })
}
let p1 = fakeAjax(2500'p1')
let p2 = fakeAjax(1500'p2')
let p3 = fakeAjax(800'p3')

Promise.all([p1, p2, p3]) 
// 所有Promise都成功才会进入then,
// then的成功回调函数中的参数是一个数组,包含all方法接收多个Promise对象数组成功返回值
            .then(res => console.log(res)) // ['p1','p2','p3']
            .catch(err => console.error(err) ) 
            
let p1 = fakeAjax(2500'p1')
let p2 = fakeAjax(1500'p2', false)
let p3 = fakeAjax(800'p3', false)
// 只要有任何一个Promise失败all就会进入catch
// catch 回调函数接收的参数是第一个失败Promise的返回值
Promise.all([p1, p2, p3])
            .then(res => console.log(res)) 
            .catch(err => console.error(err))  //  'p3'         
复制代码

any

概念 该方法接收多个 promise对象并返回一个 promise对象。多个 promise 只要有一个成功执行就会被调用promise对象方法

注意 如果有一个Promise成功 any就会返回成功,返回的值是第一个成功 promise resolve值。

语法

function fakeAjax(timeout, name, isSuccess = true{
            return new Promise((resolve, reject) => {

                setTimeout(() => {
                    console.log(name + '执行完毕')
                    if (isSuccess) {
                        resolve(name)
                    } else {
                        reject(name)
                    }
                }, timeout)

            })
        }

        let p1 = fakeAjax(2500'p1')

        let p2 = fakeAjax(1500'p2')

        let p3 = fakeAjax(800'p3')

        Promise.any([p1, p2, p3])
            .then(res => console.log(res)) // 'p3'
            .catch(err => console.error(err))
复制代码

race

概念 该方法接收多个 promise对象并返回一个 promise对象。 只要有一个完成(无论成功失败) 。返回promise对象就会调用完成Promise状态

语法

let p1 = fakeAjax(2500'p1')

let p2 = fakeAjax(1500'p2')

let p3 = fakeAjax(800'p3'false)

Promise.race([p1, p2, p3])
    .then(res => console.log(res)) 
    .catch(err => console.error(err)) // 'p3'
    
let p1 = fakeAjax(2500'p1')

let p2 = fakeAjax(500'p2')

let p3 = fakeAjax(800'p3')

Promise.race([p1, p2, p3])
    .then(res => console.log(res))  // 'p2' 
    .catch(err => console.error(err))  
复制代码

allSettled

概念 该方法接收多个 promise对象并返回一个 promise对象。必须所有的Promise都完成(无论成功/失败)该方法才会resolve一个数组,数组中包含接收所有Promise完成信息(status:成功 fulfilled, 失败 reject,value: 成功返回值,reason:失败原因 ,)

语法

let p1 = fakeAjax(2500'p1'false)

let p2 = fakeAjax(1500'p2')

let p3 = fakeAjax(800'p3'false)

let p4 = fakeAjax(300'p4')

Promise.allSettled([p1, p2, p3, p4])
            .then(res => console.log(res)) 
/* 
res 的值为 
[
    {status: "rejected", reason: "p1"},
    {status: "fulfilled", value: "p2"},
    {status: "rejected", reason: "p3"},
    {status: "fulfilled", value: "p4"},
]
*/
复制代码

resolve

概念 该方法直接创建一个成功Promise

语法

Promise.resolve(10086).then(res => console.log(res)) // 10086
复制代码

reject

概念 该方法直接创建一个失败Promise

语法

Promise.reject(new Error('失败')).catch(error => console.log(error)) // "失败"
复制代码

Async函数

概念 async 是 ES7 才有的与异步操作有关的关键字,他会将异步操作用同步代码的形式表现出来

语法 是一个使用async关键声明的函数。在函数内部配合await关键字将异步回调的代码改写成同步代码的格式

function demo () {
     new Promise(function (resolve, reject{
        let num = Math.random()

        if (num > 0.5) {
            resolve(num) // 成功调用resolve方法else {
            reject('失败了!'// 调用reject方法
        }
    })
    .then(res => console.log('成功!' + res))
    .catch(err => console.error(err) )
}
  
 // 下面的代码等价于上面的代码       
 async function asyncDemo({
    try {
        let res = await new Promise(function (resolve, reject{
        let num = Math.random()
        if (num > 0.5) {
                resolve(num) // 成功调用resolve方法else {
                reject('失败了!'// 调用reject方法
            }
        })
        console.log(res, 'async')
       }
    catch (err) {
        console.log('Error:'+ err)
   }
}

asyncDemo()
复制代码

注意

1. async 函数的返回值,不是普通对象的返回值,而是Promise对象
 async function test({
        return 'hello world'
}

 // test() 等价于 new Promise((resolve) =>  resolve('hello world'))
console.log(test()) // Promise {<resolved>: "hello world"}
test().then(r => console.log(r)) //  'hello world'   
复制代码

案例 axios的使用(Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中)

<!--引入axios三方库-->
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
// 异步函数
 async function test({
     let res = await axios('http://musicapi.leanapp.cn/search?keywords=一')
     console.log(res) 
}
// 普通函数
function test({
   axios('http://musicapi.leanapp.cn/search?keywords=二')
     .then(res => {
           console.log(res,'12313') 
    })
}
</script>
复制代码

练习 使用Promise封装ajax的get方法

 function httpGet(url{
        return new Promise((resolve, reject) => {
            let xhr = new XMLHttpRequest();
            xhr.onreadystatechange = function ({
                if (xhr.readyState == 4) {
                    if (xhr.status == 200) {
                        // 成功
                        let res = JSON.parse(xhr.responseText)
                        resolve(res)
                    } else {
                        // 失败
                        reject(new Error('失败'))
                    }

                }
            }
            xhr.open("GET", url, true);
            xhr.send();
        })     
}


httpGet('http://musicapi.leanapp.cn/search?keywords=换')
       .then(res => console.log(res))
       .catch(err => console.log(err))
复制代码
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享