小胖墩er 小胖墩er
首页
  • 前端文章

    • JavaScript
    • Vue
    • ES6
    • Git
  • Vue
  • React
  • HTML
  • CSS
  • 工具类
  • GitHub技巧
  • 博客搭建
  • 友情链接
💖关于
💻收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

小胖墩er

Better later than never.
首页
  • 前端文章

    • JavaScript
    • Vue
    • ES6
    • Git
  • Vue
  • React
  • HTML
  • CSS
  • 工具类
  • GitHub技巧
  • 博客搭建
  • 友情链接
💖关于
💻收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • JavaScript文章

  • Vue文章

  • ES6文章

    • 基本概念的使用
    • 函数
    • Class
    • 利用ES6的class类继承实现绚丽小球效果
    • 模块
    • ES6新增方法
    • Promise
      • 介绍
      • 基本用法
        • prototype.then
        • prototype.catch
        • prototype.finally
      • all
      • any
      • race
      • allSettled
      • resolve
      • reject
      • Async函数
  • Git

  • axios

  • Webpack

  • 语言框架
  • ES6文章
小胖墩er
2021-08-09

Promise

# 介绍

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

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

Promise 对象只有:从 pending 变为 fulfilled 和从 pending 变为 rejected 的状态改变。只要处于 fulfilled 和 rejected ,状态就不会再变了即 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方法,将'失败了!'传递出去
    }
})
1
2
3
4
5
6
7
8
9

# 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的回调函数
)
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# 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的回调函数
1
2
3
4
5
6
7

# prototype.finally

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

语法:

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

p.then(function(json) { })
  .catch(function(error) { })
  .finally(function() { });
1
2
3
4
5

# 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'         
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

# 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))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

# 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))  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

# 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"},
]
*/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

# resolve

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

语法:

Promise.resolve(10086).then(res => console.log(res)) // 10086
1

# reject

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

语法:

Promise.reject(new Error('失败')).catch(error => console.log(error)) // "失败"
1

# 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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

注意

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'   
1
2
3
4
5
6
7
8

案例 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>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

练习 使用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))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
在线编辑 (opens new window)
#ES6
上次更新: 2021/11/14, 07:48:46
ES6新增方法
git基本使用

← ES6新增方法 git基本使用→

最近更新
01
毛玻璃效果
11-23
02
svg基本绘制
11-23
03
滑动登录界面
11-23
更多文章>
🖥️

© 2021 小胖墩er 💌 粤ICP备2021158933号 🛀 Theme by 💝 Vdoing

  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式
×