JavaScript 系列之异步编程(三)

578 阅读3分钟

这是我参与8月更文挑战的第28天,活动详情查看:8月更文挑战

三、async/await 基础

3.1 async/await 含义

为了解决大量复杂不易读的 Promise 异步的问题,才出现的改良版。

3.2 async/await 使用

  • async 必须声明的是一个 function
  • await 必须是在这个 async 声明的函数内部使用
async function a() {
  await function() {}
}

必须是直系(作用域链不能隔代),不然会报错:Uncaught SyntaxError: await is only valid in async function。

let data = 'data'
demo  = async function () {
  const test = function () {
    await data
  }
}

3.3 async 的本质

async 声明的函数的返回本质上是一个 Promise。

(async function () {
  return '我是Promise'
})()
// 返回是Promise
//Promise {<resolved>: "我是Promise"}

等同于:

(async function () {
  return Promise.resolve('我是Promise');
})()
const demo = async function () {
  return Promise.resolve('我是Promise');
  // 等同于 return '我是Promise'
  // 等同于 return new Promise((resolve,reject)=>{ resolve('我是Promise') })
}
demo().then((result) => {
  console.log(result); // 这里拿到返回值
});

3.4 await 的本质

await 的本质是可以提供等同于”同步效果“的等待异步返回能力的语法糖。

const demo = async () => {
  let result = await new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve('我延迟了一秒')
    }, 1000)
  });
  console.log('我由于上面的程序还没执行完,先不执行“等待一会”');
}
// demo的返回当做Promise
demo().then((result) => {
  console.log('输出', result);
});

结果是:

// 我由于上面的程序还没执行完,先不执行“等待一会”
// 输出 undefined

发现输出是这个:输出 undefined。原因是 then 需要接受上一个返回的 Promise。

const demo = async ()=>{
  let result = await new Promise((resolve, reject) => {
    setTimeout(()=>{
      resolve('我延迟了一秒');
    }, 1000)
  });
  console.log('我由于上面的程序还没执行完,先不执行“等待一会”');
  return result;
}
// demo的返回当做Promise
demo().then(result=>{
console.log('输出',result); // 输出 我延迟了一秒
});

用 await 声明的异步返回,是必须“等待”到有返回值的时候,代码才继续执行下去。

const demo = async () => {
  let result = await setTimeout(() => {
    console.log('我延迟了一秒');
  }, 1000);
  console.log('我由于上面的程序还没执行完,先不执行“等待一会”');
  return result;
}
demo().then(result => {
  console.log('输出', result);
});

输出结果:

// 我由于上面的程序还没执行完,先不执行“等待一会”
// 输出 1
// 我延迟了一秒

奇怪,并没有 await 啊?setTimeout 是异步啊,问题在哪?问题就在于 setTimeout 这是个异步,但是不是 Promise!起不到“等待一会”的作用。

所以更准确的说法应该是用 await 声明的 Promise 异步返回,必须“等待”到有返回值的时候,代码才继续执行下去

记住:await 是在等待一个 Promise 的异步返回

当然这种等待的效果只存在于“异步”的情况,await 还可以用于声明一般情况下的传值。

const demo = async () => {
  let message = '我是声明值';
  let result = await message;
  console.log(result);
  console.log('我由于上面的程序还没执行完,先不执行“等待一会”');
  return result;
}
demo().then(result => {
  console.log('输出', result);
})

输出结果:

// 我是声明值
// 我由于上面的程序还没执行完,先不执行“等待一会”
// 输出 我是声明值