javascript 中异步函数的不明确行为

Ambiguous behaviour of async function in javascript

第一版代码:

console.log("before function")
function changecolor(color) {
  return new Promise((reslove, request) => {
    setTimeout(() => {
      document.body.style.backgroundColor = color
      reslove("success")
    }, 2000)
  })
}
changecolor("red")
  .then(e => {
    console.log("changed successfully")
    console.log(e)
    return changecolor("green")
  }).then(e => {
    console.log("changed successfully")
    console.log(e)
    return changecolor("orange")
  }).then(e => {
    console.log("changed successfully")
    console.log(e)
  }).catch(e => {
    console.log("unsuccessful")
    console.log(e)
  })
console.log("last line")

第一个版本输出:

 before function
 last line
 changed successfully
 success
 changed successfully
 success
 changed successfully
 success

第二版代码:

console.log("before function")
async function changecolor(color) {
  console.log("inside function")
  setTimeout(() => {
    document.body.style.backgroundColor = color
    console.log(`color is ${color}`)
    

  }, 2000)
  console.log("function end")
  return "success"
}
changecolor("red")
  .then(e => {
    console.log("changed successfully")
    console.log(e)
    return changecolor("green")
  }).then(e => {
    console.log("changed successfully")
    console.log(e)
    return changecolor("orange")
  }).then(e => {
    console.log("changed successfully")
    console.log(e)
  }).catch(e => {
    console.log("unsuccessful")
    console.log(e)
  })
console.log("last line")

第二个版本输出:

 before function
 inside function
 function end
 last line
 changed successfully
 success
 inside function
 function end
 changed successfully
 success
 inside function
 function end
 changed successfully
 success
 color is red
 color is green
 color is orange

我的问题: 当我 运行 第一个版本的代码然后我的 html 页面的颜色在 2 秒后变成不同的背景颜色但是在第二个版本的代码中,它会在 2 秒后同时变为所有背景颜色

我知道javascript是单线程的,当我们遇到setTimeOut()函数时它会执行代码的其他部分

即使它们两个中的代码相同,一个使用纯 promise,另一个使用 async 关键字,但即使我在第二版代码中的 setTimeOut() 函数之前使用 await 关键字,它们的输出也不同

我是 javascript 的新手,谁能帮帮我

async 函数的存在是为了简化使用 promise 的工作,但它们不会自动等待任何事情。如果您 await 一个承诺,那么该功能将暂停,等待该承诺解决,然后恢复。如果你从来没有 await 一个承诺,那么你的 async 函数将 运行 一直到完成,此时它 returns。 return 值是一个承诺,但由于您没有等待任何事情,该承诺会立即解决。

换句话说,解决方案 #2 不等待任何事情。它立即调用 changeColor,设置超时,然后它立即 1 进入 .then 再次调用 changeColor。你最终在开始时设置了一堆超时,然后 2 秒后它们都关闭了。

如果您想将 setTimeout 用作承诺,则需要将其包装在承诺中,就像您在第一个示例中所做的那样。

1) 这是作为一个微任务发生的,所以不是很同步