ES6 promise 多连问

注意注意!!! promise 非常常用,用过es6的都知道,自己稍微总结下!!

从什么是promise,如何创建,如何使用,都有哪些方法,为什么会产生promise,解决了什么问题? async await 来说:

1. promise 是es6 的新特性, 有三种状态 pending(未完成)/ fulfilled(已完成)/rejected(已失败) , 状态只能pending-fufilled/ pending-rejected 一旦确定就不能更改,单向。

2. 创建一个promise 使用new 关键字 new Promise或者Promise.resolve/Promise.reject都会返回一个promise 的实例对象; new Promise 参数是一个函数,函数有两个参数 是resolve, reject ; 这个函数里面可以是同步操作也可以异步操作。这个函数本身是同步调用哦。

promise 本身是同步的,不会进入到队列中,.then .catch是异步操作

执行器里面 同步方法:先改变状态 再指定回调函数,然后执行回调函数

let p = new Promise((resolve, reject) => {

console.log('1111')

resolve(2)

})

p.then(res=> {

console.log(res)

 })

console.log('2222')

会先打印1111 在打印 222  说明执行器

resolve, reject) => {} 是一个同步调用

比如简单的

执行器里面异步方法: 先指定回调函数(只是指定没有执行),再改变状态,然后再执行回调函数

let hh = new Promise((resolve, reject) => {

console.log('1111')

    setTimeout(() => {

resolve(2)

}, 2000)

})

console.log('2222')

hh.then(res=> {

console.log(res) // 2

})

Promise原型上 有.then方法接收的resolve和reject 中的数据(有两个回调,第一个回调是resolve 的数据,第二个是reject 的数据) .catch接收的是reject中的数据还可以捕获前面then抛出的错误,所以用.catch接收比较好,还有finally 成功还是失败都接收

同时.then/.catch/.finally 都会再次返回一个promise对象 ,如果里面是return 值 ,会被自动封装成一个已完成状态的promise, 所以可以链式调用

3. promise 的一些其他方法: Promise.all([p1,p2,...]).then(res => { res 也是一个数组}),特点就是传入的promise 的对象 全都resolve的话 才会进入.then的第一个回调函数中,如果失败会被.then的第二个回调函数或者.catch捕获 

Promise.race([p1,p2,...])故名思意,谁第一个先改变状态成功/失败,决定了最终的结果状态   

Promise.allSettled/ promise.any 具体见下面代码

返回的状态成功 进入.then的第一个回调函数中,如果失败会被.then的第二个回调函数或者.catch捕获 

Promise.resolve 返回一个成功/失败的promoise 对象, 如果传入的是一个非promise类型数据,则返回的是一个成功的promise对象;如果传入的是一个promise类型对象,则返回的是该对象的成功/失败状态;

Promise.catch 返回的是一直是一个失败的对象,无论传什么类型对象;传什么,返回的就是什么

Promise.race:

只要p1、p2、p3之中有一个实例先改变状态,p的状态就跟着改变。那个率先改变的 Promise 实例的返回值,就传递给p的回调函数。
传入的对象都会被执行, 但是最终只返回率先改变状态的那个promise实例的值

let p1 = new Promise((resolve, reject) => {
                setTimeout(function() {
				console.log('今天=====')
                    resolve('今天')
                }, 1000)
            })
			
			let p2 = new Promise((resolve, reject) => {
                setTimeout(function() {
				console.log('天气======')
                    resolve('天气')
                }, 500)
            })
			let p3 = new Promise((resolve, reject) => {
                setTimeout(function() {
				console.log('很好======')
                    resolve('很好')
                }, 3000)
            })
			
			let p Promise.race([p1,p2,p3]).then(res=>{
			  console.log('成功', res)
			}).catch(err=>{
			   console.log('失败', err)
			})
Promise {<pending>}
vconsole.min.js?65ce:10 天气======
vconsole.min.js?65ce:10 成功 天气
vconsole.min.js?65ce:10 今天=====
vconsole.min.js?65ce:10 很好======

Promise.all: 
(1)只有p1、p2、p3的状态都变成fulfilled,p的状态才会变成fulfilled,此时p1、p2、p3的返回值组成一个数组,传递给p的回调函数。 顺序和传入的顺序一致

(2)只要p1、p2、p3之中有一个被rejected,p的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数。

传入的数组promise 对象都会被执行 就算有reject状态的对象

let p1 = new Promise((resolve, reject) => {
                setTimeout(function() {
				console.log('今天=====')
                    resolve('今天')
                }, 1000)
            })
			
			let p2 = new Promise((resolve, reject) => {
                setTimeout(function() {
				console.log('天气======')
                    resolve('天气')
                }, 2000)
            })
			let p3 = new Promise((resolve, reject) => {
                setTimeout(function() {
				console.log('很好======')
                    resolve('很好')
                }, 3000)
            })
			
			Promise.all([p1,p2,p3]).then(res=>{
			  console.log('成功', res)
			}).catch(err=>{
			   console.log('失败', err)
			})
Promise {<pending>}
vconsole.min.js?65ce:10 今天=====
vconsole.min.js?65ce:10 天气======
vconsole.min.js?65ce:10 很好======
vconsole.min.js?65ce:10 成功 (3) ['今天', '天气', '很好']
Promise.allSettled: 
allSettled 一旦发生状态变更,状态总是fulfilled, 没有rejected

let p1 = new Promise((resolve, reject) => {
                setTimeout(function() {
				console.log('今天=====')
                    resolve('今天')
                }, 1000)
            })
			
			let p2 = new Promise((resolve, reject) => {
                setTimeout(function() {
				console.log('天气======')
                    reject('天气')
                }, 500)
            })
			let p3 = new Promise((resolve, reject) => {
                setTimeout(function() {
				console.log('很好======')
                    resolve('很好')
                }, 3000)
            })
			
			Promise.allSettled([p1,p2,p3]).then(res=>{
			  console.log('成功', res)
			}).catch(err=>{
			   console.log('失败', err)
			})
			
Promise {<pending>}
vconsole.min.js?65ce:10 天气======
vconsole.min.js?65ce:10 今天=====
vconsole.min.js?65ce:10 很好======
vconsole.min.js?65ce:10 成功 
(3) [{…}, {…}, {…}]
0: {status: 'fulfilled', value: '今天'}
1: {status: 'rejected', reason: '天气'}
2: {status: 'fulfilled', value: '很好'}
length: 3
[[Prototype]]: Array(0)
Promise.any:

只要p1 p2 p3 有一个状态是fulfilled, p的状态就是fulfilled, p的回调函数接收的是第一个先返回的fuifilled状态的值; 如果p1 p2 p3 全都是rejected 状态 p的状态才是rejected 返回的AggregateError;

let p1 = new Promise((resolve, reject) => {
                setTimeout(function() {
				console.log('今天=====')
                    resolve('今天')
                }, 1000)
            })
			
			let p2 = new Promise((resolve, reject) => {
                setTimeout(function() {
				console.log('天气======')
                    reject('天气')
                }, 500)
            })
			let p3 = new Promise((resolve, reject) => {
                setTimeout(function() {
				console.log('很好======')
                    resolve('很好')
                }, 3000)
            })
			
			Promise.any([p1,p2,p3]).then(res=>{
			  console.log('成功', res)
			}).catch(err=>{
			   console.log('失败', err)
			})
			
Promise {<pending>}
vconsole.min.js?65ce:10 成功 今天



let p1 = new Promise((resolve, reject) => {
                setTimeout(function() {
				console.log('今天=====')
                    reject('今天')
                }, 1000)
            })
			
			let p2 = new Promise((resolve, reject) => {
                setTimeout(function() {
				console.log('天气======')
                    reject('天气')
                }, 500)
            })
			let p3 = new Promise((resolve, reject) => {
                setTimeout(function() {
				console.log('很好======')
                    reject('很好')
                }, 3000)
            })
			
			let p = Promise.any([p1,p2,p3]).then(res=>{
			  console.log('成功', res)
			}).catch(err=>{
			   console.log('失败', err)
			})
			
Promise {<pending>}
vconsole.min.js?65ce:10 失败 AggregateError: All promises were rejected

 4. promise本身是同步方法, then catch finally 是异步 属于微任务

5. promise 可以链式回调,原因是.then .catch .finally 还会返回一个promise 对象 ; 中断链式调用的方法 是return 一个pending状态的promise对象;return new Promise(()=>{})

6. promise 解决了什么问题? 为什么会出现它? 

解决了地狱回调,那么又问什么是地狱回调     ;

回调: 将一个函数作为另一个函数的参数 使用 , 不会立即调用,在一定条件下触发。

function b(val) {
  console.log('bavalval===',val)
}

function a(fn) {
  setTimeout(() => {
      fn('3333')
  }, 2000)
}
a(b)
bavalval===3333

                                                                                                                                                         

地狱回调:回调里面再回调

比如: 

setTimeout(function () {
                console.log('今天')
                setTimeout(function() {
                    console.log('天气')
                    setTimeout(function() {
                        console.log('很好')
                    }, 1000)
                }, 2000)
            }, 1000)

输出:
今天
天气
很好

如果上面的用promise 来写的话 怎么写呢 ? .then 如果返回的是一个promise 对象就原样返回,如果不是,怎会自动封装成一个promise

let p1 = new Promise((resolve, reject) => {
                setTimeout(function() {
                    resolve('今天')
                }, 1000)
            })
            let p2 = new Promise((resolve, reject) => {
                setTimeout(function() {
                    resolve('天气')
                }, 2000)
            })
            let p3 = new Promise((resolve, reject) => {
                setTimeout(function() {
                    resolve('很好')
                }, 1000)
            })

            p1.then(res1 => {
                console.log(res1)
                return p2
            }).then(res2 => {
                console.log(res2)
                return p3
            }).then(res3 => {
                console.log(res3)
                return res3
            })

输出:
今天
天气
很好

如果用async await 如何实现

async 返回的promise 对象,自动封装; 是一个异步操作

await 后面接一个 promise 对象或者 方法 ,返回值 自动返回的是promse.then 里面的值

async function hd() {

            let p1 = new Promise((resolve, reject) => {
                setTimeout(function() {
                    resolve('今天')
                }, 1000)
            })
            let p2 = new Promise((resolve, reject) => {
                setTimeout(function() {
                    resolve('天气')
                }, 2000)
            })
            let p3 = new Promise((resolve, reject) => {
                setTimeout(function() {
                    resolve('很好')
                }, 1000)
            })

          let h1 =   await p1
          let h2 =    await p2
          let h3 =    await p3
          console.log(h1 + h2 + h3)
        }

输出:
今天天气很好

 await 后promise 对象很可能是rejected 状态,需要在try catch 里面获取异常

function promiseFn () {

   return new Promise((resolve, reject)=> {
       reject('错误异常')
   })
}

async function doSomething() {
  try {
    await promiseFn();
  } catch (err) {
    console.log(err);
  }
}

或者 另外一种简单的写法:
async function doSomething() {
   await promiseFn().catch(err=> console.log(err))
}

输出:
错误异常

async await 与promise 的关系

async 返回的是一个promise 对象, 如果awiat 后面跟的是promise 对象 但是这个promise 对象的状态是pending的,后续代码都不会执行,,如果是reject, 但是没有进行catch 处理,也不会执行; 如果进行了catch 处理 会执行;  此时async 返回的对象的状态和awiat 后的对象状态一致, 否则都是成功状态, 并且成功的值 是return 的值, 默认是undefined
await 阻塞后面的代码, 后续的代码相当于一个微任务, 就相当于在.then的第一个回调函数里面执行;  r

如果是一个promise 对象 ; 会等这个对象执行完毕之后 再执行 后续代码 ;

async function hd() {

             let p1 = new Promise((resolve, reject) => {
                setTimeout(function() {
                     resolve('今天')
                 }, 1000)
             })
          let h1 =   await p1
           console.log(h1 )
          console.log('11111')
          
        }
hd()

输出:
今天
11111


相当于
async function hd() {
            new Promise((resolve, reject) => {

                 setTimeout(function() {
                     resolve('今天')
                 }, 1000)
            }).then((res) => {
                 console.log(h1 )
                console.log('11111')
            })
          
        }
hd()


await 后如果是一个普通对象 , 其实就是会被包装成Promise.resolve 输出 

async function hd1() {

             let p1 = 
                setTimeout(function() {
console.log('今天')
                    
                 }, 1000)
          let h1 =   await p1
          console.log('11111')
          
        }
输出:
11111
今天

 如果await 后的promise对象状态一直是pending 会导致后续代码无法执行

async function async1 () {
  console.log('async1 start');
  await new Promise(resolve => {
    console.log('promise1')
  })
  console.log('async1 success');
  return 'async1 end'
}
async1()

只会输出 promise1
promise1

相当于
async function async1 () {
  console.log('async1 start');
 new Promise(resolve => {
    console.log('promise1')
  }).then(res => {
    console.log('async1 success');
    return 'async1 end'
})
  
}

await 如果是reject 状态 try catch 进行处理 或者直接在await 后面的那个promise对象进行catch处理(,如果是reject, 但是没有进行catch 处理,也不会执行; 如果进行了catch 处理 会执行;  )

async function async1 () {
  try {
      await async2();
  } catch (error) {
console.log(error);
      console.log('async1');
      return 'async1 success'
  }
  
}
async function async2 () {
  return new Promise((resolve, reject) => {
    console.log('async2')
    reject('error')
  })
}
async1().then(res => console.log(res))

或者

async function async1 () {
  
      await async2().catch(err=> {console.log(err)});
  
      console.log('async1');
      return 'async1 success'
  
}
async function async2 () {
  return new Promise((resolve, reject) => {
    console.log('async2')
    reject('error')
  })
}
async1().then(res => console.log(res))



或者如果没有进行catch 处理 后续代码不会执行

async function async1 () {
  
      await async2()  
  

// 下面代码不会、输出
      console.log('async1');
      return 'async1 success'
  
}
async function async2 () {
  return new Promise((resolve, reject) => {
    console.log('async2')
    reject('error')
  })
}
async1().then(res => console.log(res))

                                                                                                                               学习参考:ES6 入门教程https://es6.ruanyifeng.com/#docs/promise%23Promise-prototype-then                async 函数的含义和用法 - 阮一峰的网络日志http://www.ruanyifeng.com/blog/2015/05/async.html                                                                                                                                                                                                                                            

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值