当前位置:   article > 正文

async await 面试题_async function async1(){ console.log(1); await asy

async function async1(){ console.log(1); await async2(); console.log(2) } co

面试题

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

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");
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

在这里插入图片描述
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");
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

结果输出是 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')
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

先打印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')
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
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())
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

问题 2

async function t2 () {
  let a = await new Promise((resolve) => {});
  console.log(a); //
}
t2();
  • 1
  • 2
  • 3
  • 4
  • 5
问题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)
})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

问题 3

async function t3 () {
  let a = await new Promise((resolve) => {
    resolve();
  });
  console.log(a); 
}
t3();
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
问题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)
})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

问题 4

async function t4 () {
  let a = await new Promise((resolve) => {
    resolve("hello");
  });
  console.log(a); 
}
t4();
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
问题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)
})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

问题 5

async function t5() {
  let a = await new Promise((resolve) => {
    resolve("hello");
  }).then(() => {
    return "lala";
  });
  console.log(a); //lala
}
t5();
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
问题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();
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
问题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
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

问题 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();
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
问题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();
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

注意细节

  • async 函数执行的返回结果是一个 promise 对象,这个函数的返回值是这个 promise 状态值 resolve的值
  • await 后面如果不是一个 promise 对象,将直接返回这个值
  • await 后面如果是一个 promise 对象,将会把这个 promise 的状态 resolve 的值返回出去。
  • 以上没有考虑 reject 状态。
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/羊村懒王/article/detail/555104
推荐阅读
相关标签
  

闽ICP备14008679号