Javascript Await / Async Feature - 如果你在函数中没有await字,该怎么办?

问题描述 投票:0回答:3

我正在学习Javascript ES2017 async / await功能。已经阅读了很多关于它的内容,并且发现了等待就像收益的理解,并允许我们等待承诺完成。

来自https://javascript.info/async-await

async function showAvatar() {

  // read our JSON
  let response = await fetch('/article/promise-chaining/user.json');
  let user = await response.json();

  // read github user
  let githubResponse = await fetch(`https://api.github.com/users/${user.name}`);
  let githubUser = await githubResponse.json();

  // show the avatar
  let img = document.createElement('img');
  img.src = githubUser.avatar_url;
  img.className = "promise-avatar-example";
  document.body.append(img);

  // wait 3 seconds
  await new Promise((resolve, reject) => setTimeout(resolve, 3000));

  img.remove();

  return githubUser;
}

showAvatar();

我的问题是,我可以添加等待每一行代码吗?或者,如果我删除单词等待会发生什么?

另一个问题是,如果async / await使得代码似乎同步并按顺序运行,为什么我们根本不使用它(意味着让一切都保持同步?)

谢谢!

javascript asynchronous
3个回答
3
投票

async函数只是Promises的语法糖。它没有任何改变功能是同步的。事实上,任何async函数都会隐式返回一个Promise对象。

所有await都提供了等待Promise的便捷方式。如果删除await关键字,那么Promise将不会被“解包”,如果你的函数将对Promise的结果进行操作,那么这不是你想要的。

为了说明,这是您的异步​​函数的desberared版本:

function showAvatar() {

  let githubUser;

  // read our JSON
  return fetch('/article/promise-chaining/user.json').then(response => {
    return response.json();
  }).then(user => {
    // read github user
    return fetch(`https://api.github.com/users/${user.name}`);
  }).then(githubResponse => {
    return githubResponse.json();
  }).then(user => {
    githubUser = user;

    // show the avatar
    let img = document.createElement('img');
    img.src = githubUser.avatar_url;
    img.className = "promise-avatar-example";
    document.body.append(img);

    // wait 3 seconds
    return new Promise((resolve, reject) => setTimeout(resolve, 3000));
  }).then(() => {
    img.remove();

    return githubUser;
  });
}

所以await基本上只是添加了一个.then回调给Promise。如果没有指定await,你将只拥有一个Promise对象,而不是Promise的结果。


1
投票

await告诉运行时等待从右侧的表达式返回的promise将被实现。

在下面的代码中,在异步函数中停止控制,直到满足fetch调用返回的promise,并将发送到履行的promise的响应值打印到控制台。

async function go() {
  let response = await fetch('http://www.example.com');
  console.log(response); // print the response after some time
}
go();

如果省略了await关键字,那么控制将立即继续到函数的下一行,并且fetch返回的promise将立即打印到控制台。

async function go() {
  let response = fetch('http://www.example.com');
  console.log(response); // print the promise from fetch immediately
}
go();

await是一个上下文关键字,在标记为async的函数中使用时仅表示特殊内容。通过标记函数async,您告诉运行时:

  1. 将该功能视为发电机功能
  2. yield用户输入await(通常是承诺)的值
  3. 将函数包装在特殊处理逻辑中,以便只有在满足await产生的每个promise时才会通过函数进行

通过这种方式,可以以更接近传统同步样式的样式编写异步控制流。即。没有嵌套,回调或可见的承诺。 try..catch也可以正常使用。

正如另一个答案所提到的,asyncawait是语法糖,要求运行时在后台使用现有对象(生成器函数和Promises),以使异步代码更易于读写。

你可以等待每一行吗?

我猜你可以。如果await右侧的表达式产生了一个promise,那么就会出现上面详述的async / await行为。

如果await右边的表达式没有产生一个promise,那么我猜这个值会包含在一个已经解决的promise中,并且逻辑会继续执行上面的操作,就像这个值来自一个立即解决的promise。这是猜测。


0
投票

首先,async / await,与承诺一起工作。如果你不是从async函数调用或await句子不是then兼容,它将无法正常工作。在大多数情况下,如果你删除await,你将以Promise而不是承诺的价值结束。

其次,在某些情况下,您可能希望在解析某些异步任务时继续执行代码。

© www.soinside.com 2019 - 2024. All rights reserved.