es63---async函数

一.基本理解与基本用法

1.基本理解

异步编程,可以执行多个promise函数
async函数返回一个 Promise 对象,可以使用then方法添加回调函数。
当函数执行的时候,一旦遇到await就会先返回,等到异步操作完成,再接着执行函数体内后面的语句

function timeout(ms) {
  return new Promise((resolve) => {
    setTimeout(resolve, ms);
  });
}

async function asyncPrint(value, ms) {
  await timeout(ms);
  console.log(value);  //等待promise执行完再执行
}

asyncPrint('hello world', 50);  //50秒后输出hello world

②
由于async函数返回的是promise函数,上述例子也可以写为
async function timeout(ms) {
  await new Promise((resolve) => {
    setTimeout(resolve, ms);
  });
}

async function asyncPrint(value, ms) {
  await timeout(ms);
  console.log(value);
}

asyncPrint('hello world', 50);function time(){
        return new Promise(function(resolve){
            setTimeout(resolve,2000,"延迟");
        })
    }

    async function timeout(){
        const one=await time();
        console.log("12345");
        return one;
    }
    timeout().then(function(res){
        console.log(res);
    })
2.基本用法
 function getName(){
        const promise=new Promise(function(resolve,reject){
            try{
                setTimeout(resolve,1000,"张三");
            }
            catch(err){
                reject(err);
            }
        });
        return promise;
    }
    
function getNametwo(){
        const promise=new Promise(function(resolve,reject){
            try{
                setTimeout(resolve,1000,"男");
            }
            catch(err){
                reject(err);
            }
        });
        return promise;
    }

    async function Name(){
        const one=await getName();
        const two=await getNametwo();   //若one和two未加await输出如下图
        //执行多个promise,最后返回的是一个对象
        return{
            name:one,
            sex:two
        }            //输出{name: "张三", sex: "男"}
    }

    console.log(Name());   //输出结果如下图2,返回一个promise对象,then catch finally都可以使用
    Name().then(function(res){
        console.log(res);
    })

在这里插入图片描述
在这里插入图片描述

3.async函数的编写方式
    //函数声明
    async function getData(){};
    //函数表达式
    const data=async function(){};
    //对象
    let obj={async getData(){}};
    obj.getData().then()

二.await命令

正常情况下,await命令后面是一个 Promise 对象,返回该对象的结果。
如果不是 Promise 对象,就直接返回对应的值。

async function f() {
  // 等同于
  // return 123;
  return await 123;
}

f().then(v => console.log(v))
// 123
上面代码中,await命令的参数是数值123,这时等同于return 123

await命令后面的 Promise 对象如果变为reject状态,则reject的参数会被catch方法的回调函数接收到。

async function f() {
  await Promise.reject('出错了');
}

f().then(v => console.log(v))
.catch(e => console.log(e))
// 出错了
注意,上面代码中,await语句前面没有return,但是reject方法的参数依然传入了catch方法的回调函数。这里如果在await前面加上return,效果是一样的。

任何一个await语句后面的 Promise 对象变为reject状态,那么整个async函数都会中断执行。

async function f() {
  await Promise.reject('出错了');
  await Promise.resolve('hello world'); // 不会执行
}
上面代码中,第二个await语句是不会执行的,因为第一个await语句状态变成了reject。

有时,我们希望即使前一个异步操作失败,也不要中断后面的异步操作。这时可以将第一个await放在try…catch结构里面,这样不管这个异步操作是否成功,第二个await都会执行。

async function f() {
  try {
    await Promise.reject('出错了');
  } catch(e) {
  }
  return await Promise.resolve('hello world');
}

f()
.then(v => console.log(v))
// hello world

另一种方法是await后面的 Promise 对象再跟一个catch方法,处理前面可能出现的错误。

async function f() {
  await Promise.reject('出错了').catch(e => console.log(e));
  return await Promise.resolve('hello world');
}

f().then(v => console.log(v))
// 出错了
// hello world

三.异常处理

如果await后面的异步操作出错,那么等同于async函数返回的 Promise 对象被reject。

async function f() {
  await new Promise(function (resolve, reject) {
    throw new Error('出错了');
  });
}

f().then(v => console.log(v))
.catch(e => console.log(e))
// Error:出错了

解决方法也是将其放在try…catch代码块之中

async function f() {
  try {
    await new Promise(function (resolve, reject) {
      throw new Error('出错了');
    });
  } catch(e) {
  }
  return await('hello world');
}

await命令后面的Promise对象,运行结果可能是rejected,所以最好把await命令放在try…catch代码块中。
需要注意的问题
① 如果await后边的promise返回reject,直接将整个await抓异常
② 如果多个await之间有继发关系,就让他们一个一个走,如果他们没有关系,就让他们同时触发

 async function getData(){
        try{
            let number=await new Promise(function(resolve,reject){
                try{
                    setTimeout(resolve,1000,1);
                }
                catch(err){
                    reject(err);
                }
            });
            let data=await new Promise(function(resolve,reject){
                try{
                    setTimeout(resolve,1000,"数据");
                }
                catch(err){
                    reject(err);
                }
            });
            return{
                number:number,
                data:data
            }
        }
        catch(err){
            console.log(err);
        }
    }
    getData().then(function(res){
        console.log(res);
    })

多个await之间没有继发关系
await Promise.all()

    function getName(){
        return new Promise(function(resolve){
            setTimeout(resolve,1000,"张三")
        })
    }
    function getSex(){
        return new Promise(function(resolve){
            setTimeout(resolve,1000,"男")
        })
    }
    function getAge(){
        return new Promise(function(resolve){
            setTimeout(resolve,1000,20)
        })
    }

    async function name(){
        let data=await Promise.all([getName(),getSex(),getAge()]);
        return data;
    }

    name().then((res)=>{
        console.log(res);
    })

将上述代码改为继发

    function getName(){
        return new Promise(function(resolve){
            setTimeout(resolve,1000,"张三")
        })
    }
    function getSex(name){
        return new Promise(function(resolve){
            setTimeout(resolve,1000,"男")
        })
    }
    function getAge(age){
        return new Promise(function(resolve){
            setTimeout(resolve,1000,20)
        })
    }

    async function name(){
        let name=await getName();
        let sex=await getSex(name);
        let age=await getAge(sex);
        return age;   //隔三秒才会输出age
    }

    name().then((res)=>{
        console.log(res);
    })
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值