31Promise

异步编程的一种解决方案。

1.何为异步

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

2.如何处理异步事件

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

$.ajax({
	success:function(){
		...
	}
})

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

$.ajax({
	success:function(){
		$.ajax({
			...
        })
	}
})

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

2.基本使用

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

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

resolve和reject本身也是函数。

因为没有真正的网络请求,这里使用setTimeout模拟异步请求

这种方式一层套一层很乱

//1.使用setTimeout模拟嵌套的三次网络请求
setTimeout(() => {//第一次请求
    console.log("hello world")//第一次处理代码
    setTimeout(() => {//第二次请求
        console.log("hello vuejs")//第二次处理代码
        setTimeout(() => {//第三次请求
            console.log("hello java")//第三次处理代码
        }, 1000)
    }, 1000)
}, 1000)

使用Promise处理异步请求,调用resolve()可跳转到then方法处理代码,而then中回调中又存在一个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")//第三次处理代码
            })
        })
    })
})

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

new Promise((resolve, reject) => {
    setTimeout(() => {
    	resolve('success')
    }, 1000).then(success => {
    	console.log(success)
    })
})

网络请求中也有错误的情况,此时调用reject(),此时reject(error)catch()方法捕获到reject()中的error。

new Promise((resolve, reject) => {
    setTimeout(() => {
    	reject('error message')
    }, 1000).catch(error => {
    	console.log(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)
    })
})

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)
    })
})

3.Promise三种状态

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

3.案例

成功调用promise三种写法

1

 // 正确情况1
        new Promise((resolve,reject)=>{
            setTimeout(()=>{
                resolve('aaa')
            },1000)
        }).then(res=>{
            console.log(res,'第一层代码');
            return new Promise((resolve)=>{
                resolve(res+'111')
            })
        }).then(res=>{
            console.log(res,'第二层处理代码');
            return new Promise(resolve=>{
                resolve(res+'2222')
            })
        }).then(res=>{
            console.log(res,'第三层处理');
        })

2

    // 正确情况2
        new Promise((resolve,reject)=>{
            setTimeout(() => {
                resolve('aaa')
            }, 1000);
        }).then(res =>{
            console.log(res,'第一层处理代码');
            return Promise.resolve(res+'111')
        }).then(res=>{
            console.log(res,"第二层处理代码");
            return Promise.resolve(res+'222')
        }).then(res=>{
            console.log(res,"第三层处理代码");
        }).catch(err=>{
            console.log(err);
        })

3

// 正确情况3
        new Promise((resolve,reject)=>{
            setTimeout(() => {
                resolve('aaa')
            }, 1000);
        }).then(res =>{
            console.log(res,'第一层处理代码');
           
            return res+'111'
        }).then(res=>{
            console.log(res,"第二层处理代码");
            return res+'222'
        }).then(res=>{
            console.log(res,"第三层处理代码");
        }).catch(err=>{
            console.log(err);
        })

错误情况,可以两种错误异常写法

第一种

//  return Promise.reject('error message')

第二种

 throw 'error message' 

当执行到异常时下方就不再执行了。

  // 错误情况
        // 当出现错误时下方就不再执行了
        new Promise((resolve,reject)=>{
            setTimeout(() => {
                resolve('aaa')
            }, 1000);
        }).then(res =>{
            console.log(res,'第一层处理代码');
        //  return Promise.reject('error message')
         throw 'error message' 
         reject('error')
        }).then(res=>{
            console.log(res,"第二层处理代码");
            return res+'222'
        }).then(res=>{
            console.log(res,"第三层处理代码");
        }).catch(err=>{
            console.log(err);
        })
posted @ 2021-07-21 17:44  ajaXJson  阅读(28)  评论(0编辑  收藏  举报