async await 面试题

面试题

阅读下面代码,分析浏览器环境下的执行结果,并说明具体原因。

async function async1() {
  console.log("AAAA");
  async2(); 
  console.log("BBBB");
}
async function async2() {
  console.log("CCCC");
}

console.log("DDDD");
setTimeout(function () {
  console.log("FFFF");
}, 0);
async1();
new Promise(function (resolve) {
  console.log("GGGG");
  resolve();
}).then(function () {
  console.log("HHHH");
});
console.log("IIII");

在这里插入图片描述
async2 前加上 await

async function async1() {
  console.log("AAAA");
  await async2();  //  await new Promise(function(resolve) { resulve(undefined) })
  console.log("BBBB");
}
async function async2() {
  console.log("CCCC");
}

console.log("DDDD");
setTimeout(function () {
  console.log("FFFF");
}, 0);
async1();
new Promise(function (resolve) {
  console.log("GGGG");
  resolve();
}).then(function () {
  console.log("HHHH");
});
console.log("IIII");

结果输出是 DDDD AAAA CCCC GGGG IIII BBBB HHHH FFFF

解析

本题考察重点是 js 异步执行、 宏任务、 微任务。
这道题的坑就在于 async 中如果没有 await,那么它就是一个纯同步函数。

这道题的起始代码在第 9 行,输出DDDD
第 10 行计时器开启一个异步任务 t1(一个称呼),这个任务且为宏任务。
第 13 行函数async1执行,这个函数内没有 await 所以它其实就是一个纯同步函数,打印输出AAAA,
async1中执行async2函数,因为async2的内部也没有 await,所以它也是个纯同步函数,打印输出CCCC
紧接着打印输出BBBB
第 14 行 new Promise 执行里面的代码也是同步的,所以打印输出GGGG,resolve()调用的时候开启一个异步任务 t2(一个称呼),且这个任务 t2 是微任务,它的执行交给 then()中的第一个回调函数执行,且优先级高于宏任务(t1)执行。
第 20 行打印输出IIII,此时线程上的同步任务全部执行结束。
在执行任务队列中的异步任务时,微任务优先于宏任务执行,所以先执行微任务 t2 打印输出 HHHH,然后执行宏任务 t1 打印输出 FFFF
所以综上 结果输出是 DDDD AAAA CCCC BBBB GGGG IIII HHHH FFFF

面试题2

async function t1() {
  let a = await "lagou";
  console.log(a);
}
t1();
console.log('a')

先打印A 后执行微任务里的 let a = await “lagou”;
console.log(a);
原理其实就是Generator

问题1解析

await是一个表达式,如果后面不是一个 promise 对象,会先把表达式转换成promise

function * t1 () {
  let a = yield "lagou"
  console.log(a)
}


const generator = t1()
let result = generator.next()
result.value = Promise.resolve(result.value)
result.value.then(data => {
  generator.next(data)
})
console.log('xx')
function * t1 () {
  let a = yield 'lagou'
  console.log(a)
}

co(t1)

function co (generator) {
  const g = generator()
  function handleResult (result) {
    if (result.done) {
      return Promise.resolve(result.value)
    }
    // 如果 yield 后面的值不是 Promise 对象,保证成 Promise 对象
    if (!(result.value instanceof Promise)) {
      result.value = Promise.resolve(result.value)
    }
    return result.value.then(function (data) {
      handleResult(g.next(data))
    })
  }
  return handleResult(g.next())
}

问题 2

async function t2 () {
  let a = await new Promise((resolve) => {});
  console.log(a); //
}
t2();
问题2解析

await后面如果跟一个 promise 对象,await 将等待这个 promise 对象的 resolve 状态的值 value,且将这个值返回给前面的变量,此时的 promise 对象的状态是一个 pending 状态,没有 resolve 状态值,所以什么也打印不了。

function * t2 () {
  let a = yield new Promise((resolve) => {});
  console.log(a); //
}
const generator = t2()
const result = generator.next()
result.value.then(v => {
  generator.next(v)
})

问题 3

async function t3 () {
  let a = await new Promise((resolve) => {
    resolve();
  });
  console.log(a); 
}
t3();
问题3解析

await后面如果跟一个 promise 对象,await 将等待这个 promise 对象的 resolve 状态的值 value,且将这个值返回给前面的变量,此时的 promise 对象的状态是一个 resolve 状态,但是它的状态值是undefined,所以打印出 undefined

function * t3 () {
  let a = yield new Promise((resolve) => {
    resolve();
  });
  console.log(a); //undefined
}

const generator = t3()
const result = generator.next()
result.value.then(v => {
  generator.next(v)
})

问题 4

async function t4 () {
  let a = await new Promise((resolve) => {
    resolve("hello");
  });
  console.log(a); 
}
t4();
问题4解析

await后面如果跟一个 promise 对象,await 将等待这个promise 对象的resolve 状态的值,且将这个值返回给前面的变量,此时的promise 对象的状态是一个 resolve 状态,它的状态值是 hello,所以打印出 hello

function * t4 () {
  let a = yield new Promise((resolve) => {
    resolve("hello")
  })
  console.log(a) //hello
}

const generator = t4()
const result = generator.next()
result.value.then(v => {
  generator.next(v)
})

问题 5

async function t5() {
  let a = await new Promise((resolve) => {
    resolve("hello");
  }).then(() => {
    return "lala";
  });
  console.log(a); //lala
}
t5();
问题5解析

await后面如果跟一个promise 对象,await 将等待这个 promise 对象的 resolve 状态的值,且将这个值返回给前面的变量,此时的 promise 对象的状态是一个 resolve 状态,它的状态值是 hello,紧接着后面又执行了一个 then 方法,then 方法又会返回一个全新的 promise 对象,且这个 then 方法中的返回值会作为这个全新的 promiseresolve 的值,所以最终的结果是 lala

问题 6

async function t6() {
  let a = await fn().then((res) => {
    return res;
  });
  console.log(a); 
}
async function fn() {
  await new Promise((resolve) => {
    resolve("lagou");
  });
}
t6();
问题6解析

首先考虑 fn() 执行返回一个promise 对象,因为 fn执行没有返回值,所以这个 promise 对象的状态 resolve 的值是 undefined,且将这个 undefined 当作下一个 then 中回调函数的参数,所以打印的结果是 undefined

async function t6() {
  let a = await new Promise(function (resolve) {
    	resolve(undefined)
  	}).then((res) => {
    	return res;
  	});
  console.log(a); //undefined
}

问题 7

async function t7() {
  let a = await fn().then((res) => {
    return res;
  });
  console.log(a);
}
async function fn() {
  await new Promise((resolve) => {
    resolve("lagou");
  });
  return "lala";
}
t7();
问题7解析

首先考虑 fn() 执行返回一个 promise 对象,因为fn()执行有返回值lala,所以这个 promise 对象的状态 resolve 的值是 lala,且将这个 lala 当作下一个 then 中回调函数的参数,所以打印的结果是 lala

async function t7() {
  let a = await new Promise(function (resolve) {
    resolve('lala')
  }).then((res) => {
    return res;
  });
  console.log(a); // lala
}

t7();

注意细节

  • async 函数执行的返回结果是一个 promise 对象,这个函数的返回值是这个 promise 状态值 resolve的值
  • await 后面如果不是一个 promise 对象,将直接返回这个值
  • await 后面如果是一个 promise 对象,将会把这个 promise 的状态 resolve 的值返回出去。
  • 以上没有考虑 reject 状态。
  • 3
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值