原生JS面试题:async和await

一、解释

ES6 = ES2015

ES7= ES2016

async和await是ES7出现关键字,目的是彻底解决回调地狱,比Promise彻底。即就是:把异步的回调变成了同步的写法。

据说,async和await是回调地狱的终极解决方案。

async:异步

await:等待

二、 async定义函数的格式

语法:

​ async function 函数名()
 
​    {
 
​        try{
      let res = await 异步操作 (使用Promise) ;//res: 就是Promise里面resolve函数的参数
 
​            console.lor(res);
 
​        }catch(err){
 
​                err:就是Promise里面reject函数的参数
 
​        }
 
​          await 异步操作 (使用Promise) 
 
​    }

返回值:Promise对象;

功能:将异步操作按同步操作的方式书写,即上一步未执行完,会阻塞当前函数的进程,不影响主线程

知识点:

1)、async:修饰的函数表示函数里面有异步操作,返回值是Promise对象

2)、await:

2.1)、一般await后跟 promise对象,或者返回Promise对象的函数;

2.2)、await 修饰函数后,那么,返回值变成了Promise对象中resolve的参数;

如 Let res = await fn(); //res是函数fn返回的Promise对象里的resolve的参数。

2.3)、如果要拿到reject里参数,就使用try catch。

如:

try{
  Let res = await fn(); //res是 fn函数里Promise的resolve的参数

  }catch(err){
    err 是 fn函数里Promise的reject的参数

}

三、使用async和await:

1、只使用async关键字

使用async修饰函数,函数的返回值是Promise对象。函数本身的返回值,会作为resolve的参数;

async function f2(){
 
​    return "hello f2";  //return后面的字符串会作为 resolve函数的参数。
 
}

// 等价于:

function f2(){
 
​    return new Promise(function(resolve,reject){
 
​          resolve("hello f2");
 
​    })
 
}

2、使用async和await结合(获取resolve里的值)

1)、 await只能写在async修饰的函数里。

2)、await是等待的意思,await修饰的代码会等待。在函数里,碰到await修饰的代码时,await朝后的代码都会等待。 等到函数外面的代码执行完毕后,再执行await里的代码。

3)、一般来说:await后面接一个Proimse对象,或者返回Promise对象的函数。

await 修饰函数后,那么,返回值变成了Promise对象中resolve的参数

示例一:
async function fn() {
 
​    console.log("await前")
 
​    // await 修饰的 Promise对象的返回值是 resolve的参数,不用再写then了。
 
​    let res =  await new Promise((resolve, reject) => {
 
​        setTimeout(function () {
 
​            resolve("hhhh");
 
​        }, 1000)
 
​    })
 
​    console.log("await后:"+res)
 
}
 
fn()
 
console.log('虽然在后面,但是我先执行');
示例二:

把以上代码中,await后面的Promise对象写在一个函数里。

function testf(){
 
​    return new Promise((resolve, reject) => {
 
​        setTimeout(function () {
 
​            resolve("hhhh");
 
​        }, 1000)
 
​    })
 
}
 
async function fn() {
 
​    console.log("await前")
 
​    // await 修饰的 Promise对象的返回值是 resolve的参数,不用再写then了。
 
​    let res =  await testf();
 
​    console.log("await后:"+res)
 
}
 
fn()
 
console.log('虽然在后面,但是我先执行');
示例三:

再进一步

function testf(){
 
​    return new Promise((resolve, reject) => {
 
​        setTimeout(function () {
 
​            resolve("hhhh");
 
​        }, 1000)
 
​    })
 
}
 
 
 
async function fn() {
 
​    let res =  await testf();
 
​    console.log(res)
 
​    let res2 =  await testf();
 
​    console.log(res2)
 
}
 
fn()
示例四:

发送一个ajax请求:

$("btnLogin").onclick = function () {
 
​        getData()
 
​    }
 
​    async function getData() {
 
​        let sendStr = `username=${$("username").value}&userpass=${$("userpass").value}`;
 
​        let res = await ajax03({
 
​            method: "post",
 
​            url: "loginCheck03.php",
 
​            params: sendStr
 
​        })
 
​        success(res);
 
​    }
示例五:

发送两个ajax请求,并且后一个请求需要依赖前一个请求的结果:

 async function fn(){
 
​    // 1、验证用户名是否存在
 
​    let res = await ajax03({
 
​        url:"checkUser.php",
 
​        params:"username="+oUser.value
 
​    });    
 
​    if(res=="0"){
 
​        // 2、用户名如果不存在,则进行注册的ajax请求
 
​        let res2 = await ajax03({
 
​            method:"post",
 
​            url:"regSave.php",
 
​            params:`username=${oUser.value}&userpass=${oPass.value}`
 
​        });
 
​        if(res2=="1"){
 
​            $("messagebox").innerHTML = "注册成功,请<a href='02login.html'>登录</a>";
 
​        }else if(str=="0"){
 
​            $("messagebox").innerHTML = "注册失败!";
 
​        }
 
​    }
 
}

3、使用async和await结合(获取reject里的值)

使用try catch

格式:

try{
    若干句代码;这些代码里,只要碰到错误,就会跳到catch里。即就是:碰到错误后,try里处于错误行后面的代码不再执行。

}catch(){
    出错,
}

如:

try{
  let res1 = await ajax();

  //res1就是 resolve的参数

  let res2 = await ajax();

  //res2就是 resolve的参数

}catch(err){
  //err:如果说第一次ajax请求失败,那么err就是第一次ajax请求里reject的参数;

  //如果说第二次ajax请求失败,那么err就是第二次ajax请求里reject的参数

}
示例一:
 function getFn(){
 
​        return new Promise((resolve, reject) => {
 
​            setTimeout(function () {
 
​                if(false){
 
​                    resolve("hhhh");
 
​                }else{
 
​                    reject("出错了");
 
​                }                
 
​            }, 1000)
 
​        })
 
​    }
 
 
 
​    async function fn() {
 
​        console.log("await前")
 
​        try {
 
​            let res =  await getFn();
 
​            console.log("await后(成功):"+res)   //此处拿到的是resolve的参数;
 
​       } catch (error) {
 
​            console.log("await后(失败):"+error)  //此处拿到的是reject的参数
 
​        }
 
​    }
 
​    fn();
示例二:

发送两个ajax请求,两个ajax请求放在同一个try catch里,那么,哪个出错了,catch里拿到的就是哪个里的reject的参数

 try {
 
​            let sendStr = `username=${$("username").value}&userpass=${$("userpass").value}`;
 
​            let res = await ajax03({
 
​                method: "post",
 
​                url: "loginCheck03.php",
 
​                params: sendStr
 
​            });
 
​            success(res);
 
​            let res2 = await ajax03({
 
​                url: "loadMore.php",
 
​                params: "pageIndex=2"
 
​            });
 
​            show(res2);
 
​        } catch (error) {
 
​            console.log("error:", error);   //第一次请求出错,那么拿到的就是第一次请求的reject的参数;第二次出错,就是第二次的reject的参数;
 
​        }
posted @ 2021-11-13 10:55  沫小墨  阅读(478)  评论(0)    收藏  举报