Promise,async,await 面试题

目录

推荐先看Promise 相关知识点

5,面试题

1

结果 1,5,2,3,4

js 复制代码
const promise = new Promise((resolve, reject) => {
  console.log(1);
  setTimeout(() => {
    console.log(2);
    resolve();
    console.log(3);
  });
});

promise.then(() => {
  console.log(4);
});

console.log(5);

因为 then() 中的回调函数虽然是微任务,但也得等到 promise 变为 fulfilled 状态才会执行。

2

结果 1,3,2

js 复制代码
async function fun() {
  console.log(1); // 同步
  const n = await 2;
  console.log(n);
}

fun();
console.log(3);

因为 fun() 函数中的同步语句会直接执行,异步的才会延迟执行。

js 复制代码
// 相当于
function fun() {
  console.log(1);
  Promise.resolve(2).then((n) => {
    console.log(n);
  })
}

3

结果 1,4,2,3

js 复制代码
async function fun() {
  console.log(1); // 同步
  const n = await 2;
  console.log(n);
}

(async () => {
  await fun();
  console.log(3);
})();

console.log(4);

同理,立即执行函数执行后,await fun() 中的同步代码先执行,异步代码进入微队列等待执行。所以先输出 1 后输出 4。

4

结果 Promise {<pending>},Promise {<pending>},4,1,3,1

js 复制代码
async function fun1() {
  return 1;
}

async function fun2() {
  const n = await fun1();
  console.log(n); // 1
  return 2; // 没用被用到
}

async function fun3() {
  const n = fun2(); // 注意没有 await
  console.log(n);
  return 3;
}

fun3().then((n) => {
  console.log(n); // n 是 fun3 的返回值 3
});

fun3();

console.log(4);

1,先看同步代码的执行。

  • 第1个 fun3() 执行,会执行 fun2(),再执行 await fun1(),会将 async fun1 返回的 Promise 对象的后续处理,放到微队列中等待执行(任务1)。
js 复制代码
const n = await fun1();
console.log(n);

// 相当于
new Promise((resolve) => {
  resolve(1)
}).then((n) => {
  console.log(n);
})
  • 因为 fun2 被 async 修饰,而且还有异步代码,所以此时 fun2() 执行的结果是一个 pending 状态的 Promise 对象,所以输出 Promise {<pending>},fun3() 的后续处理:then() 的回调函数进入微队列等待执行(任务2)。
  • 第2个 fun3() 执行,再次输出 Promise {<pending>},并添加微任务3
  • 输出 4。

2,接下来看异步代码的执行。

  • 执行微队列中的任务1输出 1,任务2输出 3,任务3输出 1

5

结果 1

js 复制代码
Promise.resolve(1).then(2).then(Promise.resolve(3)).then(console.log)

参考 3.2 的知识点。then() 的参数不是函数,说明没有对前一个任务做后续处理,相当于无效代码。

js 复制代码
// 等价
Promise.resolve(1).then(console.log)

6

结果:promise1,undefined,end,promise2,promise3,promise4,Promise {<pending>},after1

js 复制代码
var a
var b = new Promise((resolve, reject) => {
  console.log('promise1')
  setTimeout(() => {
    resolve()
  }, 1000)
})
  .then(() => {
    console.log('promise2')
  })
  .then(() => {
    console.log('promise3')
  })
  .then(() => {
    console.log('promise4')
  })

a = new Promise(async (resolve, reject) => {
  console.log(a)
  await b
  console.log(a)
  console.log('after1')
  await a
  resolve(true)
  console.log('after2')
})
console.log('end')

注意,b 和 a 都是右边 Promise 执行的结果。右边先执行,再赋值给左边的变量。

1,先看同步代码执行

  • 执行 b 右边的表达式,输出 promise1,setTimeout 的回调函数进入宏队列等待执行。此时 b 被赋值为一个 pending 状态的 Promise 对象。
  • 执行 a 右边的表达式,输出 undefined(此时 a 未赋值)。
  • 执行 await b,因为此时 b 是 pending 状态,所以后续代码都不会执行,所以 a 也被赋值为一个 pending 状态的 Promise 对象。
  • 输出 end

2,再看异步代码执行

  • 没有微队列,所以执行宏队列中 setTimeout 的回调函数,将 b 变为 fulfilled 状态,接着执行后续 3个 then(),依次输出 promise2,promise3,promise4。
  • 现在 b 变为 fulfilled 状态,所以 await b 执行完成,开始执行后续代码。
  • 注意到 a 现在还是一个 pending 状态的 Promise 对象,所以输出 Promise {<pending>} ,再输出 after1
  • 执行 await a,将永远等待,因为没有更改状态的机会。

7

结果 script start,async1 start,async2,p1,script end,async1 end,p2,settimeout

js 复制代码
async function async1() {
  console.log('async1 start')
  await async2()
  console.log('async1 end')
}

async function async2() {
  console.log('async2')
}

console.log('script start')

setTimeout(() => {
  console.log('settimeout')
}, 0)

async1()

new Promise(function (resolve) {
  console.log('p1')
  resolve()
}).then(function () {
  console.log('p2')
})

console.log('script end')

1,先看同步代码执行

  • 输出 script start,setTimeout 的回调函数进入宏队列等待执行。
  • 执行 async1(),输出 async1 start。
  • 执行 await async2() 中的同步代码,输出 async2。await async2() 之后的代码,相当于在 then() 的回调函数中执行,所以进入微队列等待。
js 复制代码
await async2()
console.log('async1 end')

async function async2() {
  console.log('async2')
}

// 相当于
new Promise((resolve) => {
  console.log('async2')
  resolve()
}).then(() => {
  console.log('async1 end')
})
  • 输出 p1,then() 的回调函数进入微队列等待。
  • 输出 script end

2,再看异步代码执行。

  • 先执行微队列中的任务,输出 async1 end,再输出 p2。
  • 再执行宏队列中的任务,输出 settimeout。

以上。

相关推荐
结局无敌23 分钟前
React Native for OpenHarmony 实战:三方库 react-native-progress-steps 的鸿蒙化适配指南
javascript·人工智能·深度学习·react native·react.js·harmonyos
步步为营DotNet27 分钟前
Async 状态机要搬进运行时了:.NET 10 Runtime Async 实测,快的地方快 1.5 倍,贵的地方贵 5 倍
性能优化·c#·.net·async·runtime
涛涛ing29 分钟前
Chrome DevTools MCP 正式可用:AI 终于能自己开浏览器调试你的页面了
前端
tryCbest30 分钟前
第三篇:JavaScript 基础语法全解 + TaskFlow 逻辑实现
javascript·前端知识
after you39 分钟前
【无标题】
前端·javascript
酷炫码神41 分钟前
Day 6|ES6+ 语法:把现代 JS 写顺手,从解构到 map / filter / reduce
前端·javascript·es6
lemon_sjdk1 小时前
从一段真实的 Electron IM 前端代码,看高级前端的工程化修养
前端·electron·状态模式·im
晓得迷路了1 小时前
栗子前端技术周刊第 150 期 - Stack Overflow 开发者调查结果、TanStack Start 1.0...
javascript·css·后端
IT_陈寒1 小时前
Vite性能优化完全指南
前端·人工智能·后端
燕落南枝1 小时前
HTML 表单入门:表单容器、文本框与密码框属性详解
前端·microsoft·html