2021-03-05

关于Promise对象和Async函数的一些理解

参考文章来源:
阮一峰:http://www.imooc.com/article/20580?block_id=tuijian_wz
简书:https://www.jianshu.com/p/b4fd76c61dc9

1.什么是Promise对象

  (1)对象的状态不受外界影响,promise对象代表一个异步操作,有三种状态,pending(进行中)、fulfilled(已成功)、rejected(已失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态,这也是promise这个名字的由来“承诺”;
  (2)一旦状态改变就不会再变,任何时候都可以得到这个结果,promise对象的状态改变,只有两种可能:从pending变为fulfilled,从pending变为rejected。这时就称为resolved(已定型)。如果改变已经发生了,你再对promise对象添加回调函数,也会立即得到这个结果,这与事件(event)完全不同,事件的特点是:如果你错过了它,再去监听是得不到结果的。

2. resolve, reject和then

  resolve函数的作用是,将promise对象的状态从“pending”变为‘’resolved‘’,在异步操作成功时调用,并将异步操作的结果,作为参数传递出去;
   reject函数的作用是,将Promise对象的状态从“未完成”变为“失败”(即从 pending 变为 rejected),在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。
   也就是说,promise对象中执行到resolve和reject函数时,对象的状态也就确定了
  promise实例生成以后,可以用then方法分别指定resolved状态和rejected状态的回调函数

3. 简单例子

function timeOut (ms) {
      return new Promise(function(resolve,reject) {
                 return    setTimeout(resolve,ms,"done");
       })
}
timeOut(3000).then( function(value){
console.log(value);
})

  函数timeout在ms时间后返回一个处于fulfilled状态的promise对象,执行promise原型中的then方法打印结果。

let promise = new Promise(function(resolve, reject) {
  console.log('Promise');
  resolve();
});

promise.then(function() {
  console.log('resolved.');
});

console.log('Hi!');

// Promise
// Hi!
// resolved

  promise创建后会立即执行,然后,then方法指定的回调函数,将在当前脚本所有同步任务执行完才会执行,所以resolved最后输出。注意,调用resolve或reject并不会终结 Promise 的参数函数的执行。也就是把第二行和第三行互换,输出结果不会改变。

new Promise((resolve, reject) => {
  return resolve(1);
  // 后面的语句不会执行
  console.log(2);
})

  如果不想执行console.log(2),在resolve前加上return即可,函数执行到第一行,promise的对象已经确定,直接将参数1传到promise外面。

4. promise.all

function 摇色子(猜测){
    return new Promise((resolve, reject)=>{
        let sino = parseInt(Math.random() * 6 +1)
        if(sino > 3){
            if(猜测 === '大'){
                resolve(sino)
            }else{
                console.log('error')
                reject(sino)
            }
        }else{
            if(猜测 === '大'){
                console.log('error')
                reject(sino)
            }else{
                resolve(sino)
            }
        }
        setTimeout(()=>{
            resolve(sino)
        },300)
    })
}
Promise.all([摇色子('大'),摇色子('大')]).then((x)=>{console.log(x)},(y)=>{console.log(y)})

  promise.all里面跟一个数组,数组的每一项是一个返回promise的函数调用,then的第一个参数是所有的promise都成功后调用,拿到所有promise的结果是一个数组;第二个参数拿到的是第一个失败的值

5. async, await

      function 摇色子() {
        return new Promise((resolve, reject) => {
          let sino = parseInt(Math.random() * 6 + 1)
          setTimeout(() => {
            resolve(sino)
          }, 3000)
        })
      }
      async function test() {
        let n = await 摇色子()
        console.log(n)
      }
      test()
      function test2() {
        let n = 摇色子()
        console.log(n)
      }
      test2()

  这里resolve之后没有then方法调用,看一下返回结果。
在这里插入图片描述
  test2的输出结果是一个fulfilled状态的promise对象,而test输出结果就是4。

  await 右侧表达式的结果,对于await来说,分2个情况:

  1. 不是promise对象
  2. 是promise对象

  如果不是 promise , await会阻塞后面的代码,先执行async外面的同步代码,同步代码执行完,再回到async内部,把这个非promise的东西,作为 await表达式的结果。
  如果它等到的是一个 promise 对象,await 也会暂停async后面的代码,先执行async外面的同步代码,等着 Promise 对象 fulfilled,然后把 resolve 的参数作为 await 表达式的运算结果。正是因为test中await右边已经是一个fulfilled状态的promise对象,所以输出结果自然是resolve中的参数而不是一个promise对象了。
  问题来了,如果promise执行的是reject咋办呢?参看如下代码:

function 摇色子(猜测){
    return new Promise((resolve, reject)=>{
        let sino = parseInt(Math.random() * 6 +1)
        if(sino > 3){
            if(猜测 === '大'){
                resolve(sino)
            }else{
                reject(sino)
            }
        }else{
            if(猜测 === '大'){
                reject(sino)
            }else{
                resolve(sino)
            }
        }
        setTimeout(()=>{
            resolve(sino)
        },300)
    })
}
async function test(){
    try{
        //把await及获取它的值的操作放在try里
        let n =await 摇色子('大')
        console.log('赢了' + n)
    }catch(error){
      //失败的操作放在catch里
        console.log('输了' + error)
    }
}
test()

搭配try,catch结构,resolve出去到try, reject出去到catch结构内,输出错误信息。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值