Promise基本使用、三种状态、链式调用及简写、all方法

vue入门–基础命令+axios+案例练习
vue入门–vue常用属性、生命周期、计算属性、过滤器、组件、虚拟DOM、数组的响应式方法、页面闪烁、ES6简单语法增强
vue入门–js高阶函数(箭头函数)、v-model数据绑定、组件化、父子组件通信及访问
vue入门–插槽(具名、匿名、作用域插槽)+ES6模块化导入导出+webpack的使用(基本使用+配置使用+如何一步步演化成cli脚手架)+webpack插件使用(搭建本地服务器、配置文件分离)
vue-cli脚手架2版本及3+版本安装、目录解析、only和compiler的区别、3+版本如何改配置、箭头函数及this的指向
vue-router基本使用、路由传参、懒加载、嵌套路由、导航守卫、keep-alive
Promise基本使用、三种状态、链式调用及简写、all方法
Vuex的作用、使用、核心概念(State、Mutations、Getters、Actions、Modules)、文件抽离
axios网络请求基本使用、配置使用(全局axios和局部axios实例)、模块封装、axios拦截器

Promise

介绍

ES6中一个非常重要和好用的特性就是Promise,

1.那么Promise是做什么的呢?

Promise是异步编程的一种解决方案

2.一般什么时候会处理异步事件呢?

​ 一种很常见的就是网络请求,一般网络请求都是需要时间等待返回数据的,但是我们又不想我们程序阻塞在那里,我们就需要使用异步编程,开启一个异步任务去执行网络请求,异步任务执行完毕后再进行函数的回调来处理数据。

基本使用

定时器异步事件

一般定时器,这么使用

// 使用 setTimeout,1s后执行打印 Hello World
setTimeout(() => {
    console.log("Hello World") 
}, 1000);

封装定时任务,Promise是一个对象,使用时直接new

new Promise();

那么看下这个对象的函数(java中叫做有参构造函数)中,需要用到什么参数呢?

Promise(executor: (resolve: (value: any) => void, reject: (reason?: any) => void) => void): Promise<any>

需要一个executor函数,executor函数中有有两个函数,resolve(解决)和reject(拒绝)

new Promise((resolve, reject) => {
    // 1s后执行setTimeout中的函数回调,然后调用 resolve()又去回调了 then中的函数执行具体的操作
    setTimeout(() => {
        resolve()	// 执行resolve函数,再找then()执行
    }, 1000);
}).then(() => {
    console.log("Hello World");
})

网络请求

上面是一个普通的定时任务,假如是网络请求后拿到了数据,我们改在哪里处理,怎么拿到该处理的数据呢?

new Promise((resolve, reject) =>{
    // 假如这里执行了网络请求
    处理网网络请求函数{
        function(res){
            resolve(res.data);	// 成功时传入 数据,再走 then
        },
        function(err){
            reject("err message");	// 失败时,传入错误信息
        }
    );
}).then(data => {
    // 处理data数据,与页面进行交互
}).catch(err => {
    // 捕获异常,进行处理
})

Promise三种状态

当我们开发中有异步操作时,可以给异步操作包装一个Promise。

了解一下:

sync : 同步操作

async : 异步操作

异步操作之后会有三种状态:

  • pending:等待状态,比如正在进行网络请求或者定时器未到时间
  • fulfilled:满足状态,我们主动调用了 resolve时,就处于此状态,并且会去回调.then()
  • rejected:拒绝状态,我们主动回调了reject时,处于该状态,并且会回调.catch()

其实除了上面说的 resolve回调then(),reject回调catch外,then中也可以同时处理resolve和reject。看一下then中需要的函数:

then(onfulfilled?: (value: any) => any, onrejected?: (reason: any) => PromiseLike<never>): Promise<any>

then中可接收两个函数,一个是处理fulfilled的(调用了resolve()的满足状态),另一个就是处理rejected的(调用了reject()的拒绝状态)。

具体实例:

new Promise((resolve, reject) =>{
    // 假如这里执行了网络请求
    axios.get("http://127.0.0.1:8080/app/report/test").then(
        function(res){
            resolve(res.data);
        },
        function(err){
            reject("err message");
        }
    );
}).then(data => {	// 成功时调用第一个函数
    // 处理数据 data
}, err => {	// 失败时,调用第二个函数
    // 处理错误信息
    console.log(err)
})

Promise的链式调用

我们在使用Promise时无论是调用完then还是catch最后都会返回一个Promise对象。那么我们的代码其实是可以链式调用的

假如要完成一个情景,我们进行了网络请求拿到了数据 abc,然后需要给abc拼接一些东西,而且要拼接好几次,那么如何处理呢?

new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve('abc')
    }, 1000);
}).then(res => {	// 每次then执行完 返回一个 Promise对象
    console.log("第一层封装")
    return new Promise((resolve, reject) => {
        resolve(res + "1111")
    })
}).then(res => {
    console.log("第二层封装")
    return new Promise(resolve => {		// new Promise,若只需要resolve函数,那么reject可省略
        resolve(res + "2222")
    })
}).then(res => {
    console.log(res, "返回结果")
})

在这里插入图片描述

简写方式一:

上文中

return new Promise((resolve, reject) => {
    resolve(res + "1111")
})

可以简写为

return Promise.resolve(res + "1111")

具体实现:

new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve('abc')
    }, 1000);
}).then(res => {
    console.log("第一层封装")
    return Promise.resolve(res + "1111")
}).then(res => {
    console.log("第二层封装")
    return Promise.resolve(res + "2222")
}).then(res => {
    console.log(res, "返回结果")
})

简写方式二:

then中也会自动返回Promise的封装,也就是此句仍可简写:

return Promise.resolve(res + "1111")

简写为:

return res + "1111"

具体实现:

new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve('abc')
    }, 1000);
}).then(res => {
    console.log("第一层封装")
    return res + "1111"
}).then(res => {
    console.log("第二层封装")
    return res + "2222"
}).then(res => {
    console.log(res, "返回结果")
})

假如中间执行时,出现了故障

new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve('abc')
    }, 1000);
}).then(res => {
    console.log("第一层封装")
    return Promise.reject("失败了")	// 这里出现故障,执行了reject,会去直接找catch,其他跳过
}).then(res => {
    console.log("第二层封装")
    return res + "2222"
}).then(res => {
    console.log(res, "返回结果")
}).catch(err => {
    console.log(err)
})

在这里插入图片描述

其实不止执行Promise.reject()走到catch中,我们手动抛出的异常,catch仍然可以捕获到。

// 方式一
return Promise.reject("失败了")

// 方式二
throw "失败了"

Promise的all方法

假如有一个场景:需要两个网络请求都获取到数据后,再进行后续的数据处理。通常情况下我们是怎么处理的呢?我们可能会这么做:在每个回调方法内部都去执行一个函数,在这个函数中判断两个请求的数据是否都获取到了,然后再进行处理。

let result1 = false
let result2 = false
ajax({
    url:"",
    success: function(){
        ...
        result1 = true
        handlerResult()
    }
})

ajax({
    url:"",
    success: function(){
        ...
        result2 = true
        handlerResult()
    }
})

function handlerResult(){
    if(result1 && result2) {
    	// 处理数据   
	}
}

但是呢,过于麻烦。Promise为我们提供了这种场景的解决方案。

下面以setTimeout模拟网络请求延迟后,获取到数据

Promise.all([
    new Promise((resolve, reject) => {
        setTimeout(() => {	
            resolve({name:"wlh1", age:21})
        }, 1000);
    }),
    new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve({name:"wlh2", age:21})
        }, 2000);
    })
]).then(results => {	// 只有当两个Promise包装的异步请求执行完以后,才会执行then中的
    console.log(results[0]) // 第一个网络请求的结果
    console.log(results[1]) // 第二个网络请求的结果
})
vue入门–基础命令+axios+案例练习
vue入门–vue常用属性、生命周期、计算属性、过滤器、组件、虚拟DOM、数组的响应式方法、页面闪烁、ES6简单语法增强
vue入门–js高阶函数(箭头函数)、v-model数据绑定、组件化、父子组件通信及访问
vue入门–插槽(具名、匿名、作用域插槽)+ES6模块化导入导出+webpack的使用(基本使用+配置使用+如何一步步演化成cli脚手架)+webpack插件使用(搭建本地服务器、配置文件分离)
vue-cli脚手架2版本及3+版本安装、目录解析、only和compiler的区别、3+版本如何改配置、箭头函数及this的指向
vue-router基本使用、路由传参、懒加载、嵌套路由、导航守卫、keep-alive
Promise基本使用、三种状态、链式调用及简写、all方法
Vuex的作用、使用、核心概念(State、Mutations、Getters、Actions、Modules)、文件抽离
axios网络请求基本使用、配置使用(全局axios和局部axios实例)、模块封装、axios拦截器
  • 4
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值