Geeks_Z の Blog Geeks_Z の Blog
首页
  • 学习笔记

    • 《HTML》
    • 《CSS》
    • 《JavaWeb》
    • 《Vue》
  • 后端文章

    • Linux
    • Maven
    • 汇编语言
    • 软件工程
    • 计算机网络概述
    • Conda
    • Pip
    • Shell
    • SSH
    • Mac快捷键
    • Zotero
  • 学习笔记

    • 《数据结构与算法》
    • 《算法设计与分析》
    • 《Spring》
    • 《SpringMVC》
    • 《SpringBoot》
    • 《SpringCloud》
    • 《Nginx》
  • 深度学习文章
  • 学习笔记

    • 《PyTorch》
    • 《ReinforementLearning》
    • 《MetaLearning》
  • 学习笔记

    • 《高等数学》
    • 《线性代数》
    • 《概率论与数理统计》
  • 增量学习
  • 哈希学习
GitHub (opens new window)

Geeks_Z

AI小学生
首页
  • 学习笔记

    • 《HTML》
    • 《CSS》
    • 《JavaWeb》
    • 《Vue》
  • 后端文章

    • Linux
    • Maven
    • 汇编语言
    • 软件工程
    • 计算机网络概述
    • Conda
    • Pip
    • Shell
    • SSH
    • Mac快捷键
    • Zotero
  • 学习笔记

    • 《数据结构与算法》
    • 《算法设计与分析》
    • 《Spring》
    • 《SpringMVC》
    • 《SpringBoot》
    • 《SpringCloud》
    • 《Nginx》
  • 深度学习文章
  • 学习笔记

    • 《PyTorch》
    • 《ReinforementLearning》
    • 《MetaLearning》
  • 学习笔记

    • 《高等数学》
    • 《线性代数》
    • 《概率论与数理统计》
  • 增量学习
  • 哈希学习
GitHub (opens new window)
  • Linux

  • Java

  • 微服务笔记

  • MySQL

  • Nginx

  • HTML

  • CSS

  • JavaWeb

  • Vue

    • Start
    • Node和NPM
    • 快速入门
    • Vue实例
    • 组件化
    • 模块化
    • webpack
    • vue-cli
    • Promies
      • 什么是 Promies
      • Promise 的基本使用
        • 什么时候使用 Promise
        • Promise 对象
      • Promise 的三种状态
      • Promies 的链式调用
      • Promies 的 all 使用
    • Vuex
    • Axios
    • vue-router
    • ref $refs(元素、组件引用 )
    • 生命周期
    • Mix(混入)配置项
    • 安装插件 use()
    • 功能样式
    • 项目开发配置
    • 样式绑定
    • 事件
  • Git

  • 开发规范

  • SpringCloud微服务权限系统

  • bug

  • Software

  • ProgramNotes
  • Vue
Geeks_Z
2022-10-24
目录

Promies

Promies

什么是 Promies

简单说 Promise 是异步编程的一种解决方案。

Promise 是 ES6 中的特性。

什么是异步操作?

网络请求中,对端服务器处理需要时间,信息传递过程需要时间,不像我们本地调用一个 js 加法函数一样,直接获得1+1=2的结果。这里网络请求不是同步的有时延,不能立即得到结果。

如何处理异步事件?

对于网络请求这种,一般会使用回调函数,在服务端传给我数据成功后,调用回调函数。例如 ajax 调用。

$.ajax({
	success:function(){
		...
	}
})
1
2
3
4
5

如果碰到嵌套网络请求,例如第一次网络请求成功后回调函数再次发送网络请求,这种代码就会让人很难受。

$.ajax({
	success:function(){
		$.ajax({
			...
        })
	}
})
1
2
3
4
5
6
7

如果还需要再次网络请求,那么又要嵌套一层,这样的代码层次不分明很难读,也容易出问题。

Promise 的基本使用

什么时候使用 Promise

解决异步请求冗余这样的问题,promise 就是用于封装异步请求的。

Promise 对象

new Promise((resolve, reject) => {})
1

Promise 对象的参数是一个函数(resolve, reject) => {},这个函数又有 2 个参数分别是resolve和reject。这 2 个参数本身也是函数,是不是有点绕?后面还有回调函数then(func)的参数也是一个函数。

模拟定时器的异步事件

用定时器模拟网络请求,定时一秒为网络请求事件,用 console.log()表示需要执行的代码。

//1.使用setTimeout模拟嵌套的三次网络请求
setTimeout(() => {
  //第一次请求
  console.log('hello world') //第一次处理代码
  setTimeout(() => {
    //第二次请求
    console.log('hello vuejs') //第二次处理代码
    setTimeout(() => {
      //第三次请求
      console.log('hello java') //第三次处理代码
    }, 1000)
  }, 1000)
}, 1000)
1
2
3
4
5
6
7
8
9
10
11
12
13

一层套一层,看起是不是很绕。

使用 promise 来处理异步操作

//参数 -> 函数
// resolve和reject本身也是函数
//then()的参数也是一个函数
new Promise((resolve, reject) => {
  setTimeout(() => {
    //第一次网络请求
    resolve()
  }, 1000)
}).then(() => {
  console.log('hello world') //第一次处理代码
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      //第二次网络请求
      resolve()
    }, 1000).then(() => {
      console.log('hello vuejs') //第二次处理代码
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          //第三次网络请求
          resolve()
        }, 1000)
      }).then(() => {
        console.log('hello java') //第三次处理代码
      })
    })
  })
})
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

是不是觉得代码还要更复杂了?仔细看看第一个如果使用了多个就找不到对应关系了。相反第二个流程就很清楚,调用resolve()就能跳转到then()方法就能执行处理代码,then()回调的返回值又是一个Promise对象。层次很明显,只要是then()必然就是执行处理代码,如果还有嵌套必然就是返回一个 Promise 对象,这样调用就像 java 中的 StringBuffer 的 append()方法一样,链式调用。

new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('success')
  }, 1000).then(success => {
    console.log(success)
  })
})
1
2
3
4
5
6
7

setTimeout()模拟的是网络请求,而 then()执行的是网络请求后的代码,这就将网络请求和请求得到响应后的操作分离了,每个地方干自己的事情。在 resolve 中传参了,那么在 then()方法中的参数就有这个参数,例如 data。

网络请求中也会有失败情况?例如网络堵塞。

如何处理失败情况,此时就要用到 reject()

new Promise((resolve, reject) => {
  setTimeout(() => {
    reject('error message')
  }, 1000).catch(error => {
    console.log(error)
  })
})
1
2
3
4
5
6
7

此时reject(error),catch()方法捕获到reject()中的 error。

合起来

new Promise((resolve, reject) => {
  setTimeout(() => {
    // 成功的时候调用resolve()
    // resolve('hello world')

    // 失败的时候调用reject()
    reject('error message')
  }, 1000)
    .then(success => {
      console.log(success)
    })
    .catch(error => {
      console.log(error)
    })
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

拿 ajax 来举例子:

new Promise((resolve, reject) => {
  $.ajax({
    success: function () {
      // 成功的时候调用resolve()
      // resolve('hello world')

      // 失败的时候调用reject()
      reject('error message')
    },
  })
    .then(success => {
      console.log(success)
    })
    .catch(error => {
      console.log(error)
    })
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

Promise 的三种状态

https://gitee.com/geeks_z/MacImages/raw/master/202204071012186.png

  • pending:等待状态,比如正在进行的网络请求还未响应,或者定时器还没有到时间
  • fulfill:满足状态,当我们主动回调了 resolve 函数,就处于满足状态,并会回调 then()
  • reject:拒绝状态,当我们主动回调 reject 函数,就处于该状态,并且会回调 catch()

Promies 的链式调用

  1. 网络请求响应结果为 hello ,打印 hello
  2. 处理: hello world ,打印 hello world
  3. 处理: hello world,vuejs ,打印 hello world,vuejs
new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('hello')
  }, 1000)
}).then(res => {
  console.log(res) //打印hello
  return new Promise(resolve => {
    resolve(res + ' world')
  }).then(res => {
    console.log(res) //打印hello world
    return new Promise(resolve => {
      resolve(res + ',vuejs')
    }).then(res => {
      console.log(res) //打印hello world,vuejs
    })
  })
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

链式调用就是then()方法的返回值返回一个 Promise 对象继续调用then(),此外还有简写Promise.resolve()。

new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('hello')
  }, 1000)
})
  .then(res => {
    console.log(res) //打印hello
    return Promise.resolve(res + ' world')
  })
  .then(res => {
    console.log(res) //打印hello world
    return Promise.resolve(res + ',vuejs')
  })
  .then(res => {
    console.log(res) //打印hello world,vuejs
  })
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

还可以直接省略掉Promise.resolve()

new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('hello')
  }, 1000)
})
  .then(res => {
    console.log(res) //打印hello
    return res + ' world'
  })
  .then(res => {
    console.log(res) //打印hello world
    return res + ',vuejs'
  })
  .then(res => {
    console.log(res) //打印hello world,vuejs
  })
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

如果中途发生异常,可以通过catch()捕获异常

new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('hello')
  }, 1000)
})
  .then(res => {
    console.log(res) //打印hello
    return res + ' world'
  })
  .then(res => {
    console.log(res)
    // return Promise.reject('error message')//发生异常
    throw 'error message' //抛出异常
  })
  .then(res => {
    console.log(res) //打印hello world,vuejs
  })
  .catch(error => {
    console.log(error)
  })
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

也可以通过throw抛出异常,类似 java

throw 'error message' //抛出异常
1

Promies 的 all 使用

有这样一个情况,一个业务需要请求 2 个地方(A 和 B)的数据,只有 A 和 B 的数据都拿到才能走下一步。

ajax 实现

$.ajax({
    ...//结果A
    resultA = true
    callback()
})
$.ajax({
    ...//结果B
    resultB = true
    callback()
})
//回调函数
function callback(){
    if(resultA&&resultB){
        ...
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

由于不知道网络请求 A 和网络请求 B 哪个先返回结果,所以需要定义一个函数只有 2 个请求都返回数据才回调成功。

Promise 实现

Promise.all([
  new Promise((resolve, resjct) => {
    $.ajax({
      url: 'url1',
      success: function (data) {
        resolve(data)
      },
    })
  }),
  new Promise((resolve, resjct) => {
    $.ajax({
      url: 'url2',
      success: function (data) {
        resolve(data)
      },
    })
  }).then(results => {
    console.log(results)
  }),
])
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

上面是伪代码,只是包装了 ajax,ajaxA 和 ajaxB 的结果都放在resolve()中,Promise 将其放在results中了,使用setTimeout模拟。

Promise.all([
  new Promise((resolve, reject) => {
    setTimeout(() => {
      //  请求A
      resolve('结果A')
    }, 1000)
  }),
  new Promise((resolve, reject) => {
    setTimeout(() => {
      //  请求B
      resolve('结果B')
    }, 1000)
  }),
]).then(results => {
  console.log(results)
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#Vue
上次更新: 2025/02/26, 08:57:57
vue-cli
Vuex

← vue-cli Vuex→

最近更新
01
RAIL
02-26
02
IOCTF
02-25
03
DGM
02-25
更多文章>
Theme by Vdoing | Copyright © 2022-2025 Geeks_Z | MIT License
京公网安备 11010802040735号 | 京ICP备2022029989号-1
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式