美文网首页Web 前端开发
javascript之异步函数

javascript之异步函数

作者: toldo | 来源:发表于2019-07-03 17:12 被阅读0次

这篇文章详细讲解了JavaScript中的异步函数。 JavaScript中的异步代码在很短的时间内从回调发展为Promise,再到ES2017的异步函数,现在我们可以像编写同步代码那样编写基于 Promise 的代码,而且还不会阻塞主线程。

为什么需要async/await?

当promise在ES2015中引入时,目的是解决异步代码的问题,但是promise不是最终的解决方案。

虽然Promise解决了著名的回调地狱,但是它自己引入了语法复杂性。

所以ES2017增加了异步函数,提高了代码可读性,对不太熟悉 Promise 的人而言,帮助就更大了。

async/await使代码看起来像是同步的,但它在后台是异步和非阻塞的。

工作原理

异步函数返回一个promise,如下例所示:

const doSomethingAsync = () => {
    return new Promise((resolve) => {
        setTimeout(() => resolve('I did something'), 3000)
    })
}

调用一个异步函数时,您先要设置一个await,当您 await 某个 Promise 时,函数暂停执行,直至该 Promise 产生结果,并且暂停并不会阻塞主线程。 如果 Promise 执行,则会返回值。 如果 Promise 拒绝,则会抛出拒绝的值。因为异步函数去掉了所有回调。提高了代码的可读性,这是一个例子:

const doSomething = async () => {
    console.log(await doSomethingAsync())
}

一个简单的例子

这是异步函数async / await的简单示例:

const doSomethingAsync = () => {
    return new Promise((resolve) => {
        setTimeout(() => resolve('I did something'), 3000)
    })
}
const doSomething = async () => {
    console.log(await doSomethingAsync())
}
console.log('Before')
doSomething()
console.log('After')

上面代码执行结果如下:

Before
After
//after 3s
I did something 

Promise详解

将async关键字添加到任何函数意味着该函数将返回一个promise。即使它没有声明,它也会在内部使它返回一个promise。
这就是此代码有效的原因:

const aFunction = async () => {
  return 'test'
}
// This will alert 'test'
 aFunction().then(alert)

它和以下一样:

const aFunction = async () => {
  return Promise.resolve('test')
}
// This will alert 'test'
aFunction().then(alert) 

代码更易读

正如上面示例所见,与回调和promise代码相比,异步函数代码看起来非常简单。

我们下面用更复杂一点的代码来演示。

例如,以下是使用promises获取JSON资源并解析它的方法:

const getFirstUserData = () => {
    // get users list
    return fetch('/users.json') 
        // parse JSON
        .then(response => response.json()) 
        // pick first user    
        .then(users => users[0]) 
        // get user data
        .then(user => fetch(`/users/${user.name}`)) 
        // parse JSON
        .then(userResponse => response.json()) 
}
getFirstUserData() 

以下是使用await / async提供的相同功能:

const getFirstUserData = async () => {
    // get users list
    const response = await fetch('/users.json') 
    // parse JSON
    const users = await response.json() 
    // pick first user
    const user = users[0] 
    // get user data
    const userResponse = await fetch(`/users/${user.name}`) 
    // parse JSON
    const userData = await user.json() 
    
    return userData
}
getFirstUserData()

链接多个异步函数

异步函数可以非常容易地链接,并且语法比简单的promise更具可读性:

const promiseToDoSomething = () => {
    return new Promise(resolve => {
        setTimeout(() => resolve('I did something'), 10000)
    })
}
const watchOverSomeoneDoingSomething = async () => {
    const something = await promiseToDoSomething()
    return something + ' and I watched'
}
const watchOverSomeoneWatchingSomeoneDoingSomething = async () => {
    const something = await watchOverSomeoneDoingSomething()
    return something + ' and I watched as well'
}
watchOverSomeoneWatchingSomeoneDoingSomething().then((res) => {
    console.log(res)
})

将打印:

 I did something and I watched and I watched as well

调试更简单

调试promise很难,因为调试器不会调试异步代码。
Async / await使得这非常简单,因为就像调试同步代码一样。

相关文章

  • part1整理

    函数式编程:JavaScript函数式编程指南 异步编程:异步编程 Promise源码 JavaScript基础知...

  • javascript之异步函数

    这篇文章详细讲解了JavaScript中的异步函数。 JavaScript中的异步代码在很短的时间内从回调发展为P...

  • JavaScript异步编程好文摘要

    JavaScript之异步编程简述JavaScript异步编程

  • 【Dart】异步函数

    异步函数 JavaScript中,异步调用通过Promise来实现async函数返回一个Promise。await...

  • Async/Await 函数用法

    JavaScript编程异步操作解决方案:回调函数 => Promise对象 => Generator函数 => ...

  • AJAX-全集

    同步+异步 Ajax同步+异步 JavaScript之(AJAX) JQuery之(AJAX) JQuery-有f...

  • Nodejs 请求中的异步陷阱

    异步和回调 JavaScript中有一些居家旅行必备的异步函数, 例如 setInterval, setTimeo...

  • 含答案的面试题总结

    1. 说说JavaScript中有哪些异步编程方式? 1. 回调函数 回调函数是异步编程的基本方法。其优点是易编写...

  • 《全栈工程师修炼指南》学习笔记 15

    异步编程 JavaScript 回调函数容易引起回调地狱 后来有了 Promise,可以将回调函数以 then 的...

  • js异步、同步函数

    简单来说: 使用回调函数、延迟器就是异步函数,否则就同步函数 Javascript语言的执行环境是"单线程" 所谓...

网友评论

    本文标题:javascript之异步函数

    本文链接:https://www.haomeiwen.com/subject/geechctx.html