在本文中,我们将探讨async/await对于每个Javascript开发人员来说,异步编程的首选工具。如果您不熟悉javascript,请不要担心,本文将帮助您async/await从头开始理解。
介绍async/await 是javascript中的一种模式,可使您的代码以同步方式执行,但又不影响javascript的异步行为。
定义异步功能要定义一个异步函数,您所要做的只是在函数定义之前添加一个async关键字。
// async function always returns a promise async function greet() { return "hello"; }
轻松自在!😎。在函数名称前使用async关键字
使该函数返回一个承诺。
函数返回时解析。
抛出错误时最终拒绝。
这意味着您每次要创建一个Promise时都不需要声明返回Promise.new()。
为了证明异步函数返回了一个Promise,我们可以快速附加一个then块以打印其值。
async function greet() { return "Hello from an async function" } greet().then(message => console.log(message)); //Hello from an async function
使用等待和执行异步功能不冷静,我们可以做的then(),并catch()在一个async功能?但这不是异步async函数的真正功能,函数的真正潜力在于await语句。
await 使函数以同步方式执行,同时将控件保持在该行中,直到等待方法完成其执行。
async function greet() { return "Hello from an async function" } async function execute() { const message = await greet(); console.log(message) }
这是我们需要记住的一些经验法则。
👉等待只能在异步函数内使用
async如果我们在函数内部使用await,则必须声明一个函数,反之则不然。
让我这样说。如果await在方法内部使用语句,则该方法必须是async方法,否则编译器会大吼大叫。
async function greet() { return "Hello from an async function"; } function execute() {//this function must be async const message = await greet(); console.log(message) } /* SyntaxError: await is only valid in async function */
但是声明一个函数async并不一定意味着我们将始终await在其内部使用它。这greet()是一个async方法,但是await里面没有任何语句。
wait当调用函数,返回promise或为异步函数时,await才有意义
//not an async function function greet() { return "Hello from an async function"; } async function execute() { const message = await greet(); console.log(message); //Hello from an async function }
尽管代码的工作原理与上一代码完全相同,但是await对synchronous函数进行操作没有任何意义。我想知道您对此有何想法?
使用await的一个重要方面是它阻塞了下一行代码的执行,直到执行await块为止。
const asyncGreet = () => new Promise(resolve => setTimeout(resolve, 2000)); (async function execute() { console.log("before executing"); await asyncGreet(); //blocks execution here // 👇 executed once await is finished console.log("I will be executed after 2000ms"); })();
现在您必须怀疑是否正在等待使代码同步,为什么我们要使用它呢?NodeJ或浏览器Javascript是单线程环境,一次执行一项任务,由于它们的异步行为而被广泛使用,而我们正在失去这些行为。那有什么意义呢?
是的,您是对的,但是如果您在大多数情况下都观察到,我们需要执行与他人有关的任务。
async function subscribeToNewsLetter() { const user = await findUser(id); //👇methods need user email to execute await subscribe(user.email) await sendNotification(user.email) }
没错 但是互不相关的代码呢?好吧,还有一个替代方法,即(Promise.all)。
const asyncGreet = (name) => new Promise((resolve) => setTimeout(resolve(`Hello ${name}`), 2000)); const names = ['john', 'jane', 'david']; (async function() { const greetingPromises = names.map(name => asyncGreet(name)); console.log(await Promise.all(greetingPromises)); })();
我知道上面的代码是一个人为的示例,在这里重要的是我们正在利用的力量Promise.all来执行所有的诺言
处理错误Async/Await。使用async / await处理错误非常容易,我们可以使用我们的老朋友try / catch块来实现这一点。
async function subscribeToNewsLetter() { try { const user = await findUser(id); await subscribe(user.email) await sendNotification(user.email) } catch(err) { //handle error } }
还有另一个版本,我们可以将catch处理程序直接附加到await块。我个人不使用它,但是如果您愿意,可以尝试一下。
await asyncGreet().catch(err => console.log(err);
2倍的可读性,易于调试
以下代码使用Promise通过id查找用户,分配配置文件信息,然后查找用户的订阅。