JavaScript 中,用 async + await 和直接同步方式执行有什么区别?意义是什么?

你一定要先理解以下重点内容:

你要把 JS 里执行分为两种。

第一种是实打实必须由 JS 线程执行的,比如做一些去算一个文件的 MD5 值,这种一般没人写异步,没好处,都是同步计算。

第二种不是由 JS 线程去执行,只是 JS 把任务提交给它,然后傻了吧唧的啥也不干等它完成并返回结果给自己。比如你调用浏览器接口去网络上下载图片,此时你的 JS 线程是把任务提交给了浏览器,然后一直等浏览器把结果返回给你。干活的是浏览器不是你 JS 线程。

对于不干活的情况,就得用异步的写法了,不然轻则执行效率低下,重则页面卡死,毕竟页面上那么多事等着 JS 线程去干,特别是现在的网站内容都是靠 JS 动态加载的。

以前使用的方法是回调,就是调用接口时同时传一个函数,告诉浏览器或谁执行完任务时调用函数,然后我们在函数中放一些需要执行完任务才能处理的事情。

比如让浏览器去下图片,我们就把显示图片放到函数中,这个函数就被称为回调函数。你们常见的什么 onloadonready 都是这个意思。

function download(callback) {
    // 这个下载花费 5 秒钟
    let file = "我是文件哦"
    setTimeout(() => callback(file), 5000)
}

console.log("开始执行了~")
console.log("先去下个图片~")

// 下载好了通知我就行,不等你了
download((file) => {
    console.log("下载完成:" + file)
    console.log("显示图片")
})

console.log("做其他事情去了~")

// 开始执行了~
// 先去下个图片~
// 做其他事情去了~

// 5 秒后......

// 下载完成:我是文件哦
// 显示图片

但假如,我要下个文件,他的下载链接保存在 A文件里, A文件的下载链接保存在 B文件里, B文件的下载链接保存在 C文件里。

那我必须先下C文件,等C下完了拿到B的链接下B文件,再等B下完了去下A文件,最后才能在A文件里拿到我的文件下载链接。(没有这么蠢的场景,但多个任务依次依赖前一个任务完成才能处理的情况还是很常见的)

这样就会形成多层嵌套的回调,就被称为回调地狱。

function download(callback) {
    // 这个下载花费 5 秒钟
    let file = "我是文件哦"
    setTimeout(() => callback(file), 5000)
}

console.log("开始执行了~")
console.log("先去下个文件~")

// 下载好了通知我就行,不等你了
download((file) => {
    console.log("下载 C 完成")
    console.log("拿到 B 的链接")
    download((file) => {
        console.log("下载 B 完成")
        console.log("拿到 A 的链接")
        download((file) => {
            console.log("下载 A 完成")
            console.log("拿到 最终文件 的链接")
            download((file) => {
                console.log("下载 最终文件 完成")
            })
        })
    })
})

console.log("做其他事情去了~")

于是乎,async + await 就出现了,它可以让我们用看起来像同步的方式去写异步的程序。

对于 async 和 await 千万不要恐怖,你把它们理解成回调的语法糖就行了,而回调函数的内容就是 await 之后的部分。

第一段的代码就可以改写成:

async function download() {
    // 这个下载花费 5 秒钟

    return new Promise((resolve, reject) => {
        let file = "我是文件哦"
        setTimeout(() => resolve(file), 5000)
    })
}

async function showImage() {
    let file = await download()
    // 以下是之前回调函数的内容
    console.log("下载完成:" + file)
    console.log("显示图片")
}

console.log("开始执行了~")
console.log("先去下个图片~")

showImage()

console.log("做其他事情去了~")

// 开始执行了~
// 先去下个图片~
// 做其他事情去了~

// 5 秒后......

// 下载完成:我是文件哦
// 显示图片

不过乍看之下好像还略微复杂了一点,但如果改写第二个程序呢?

async function download() {
    // 这个下载花费 5 秒钟

    return new Promise((resolve, reject) => {
        let file = "我是文件哦"
        setTimeout(() => resolve(file), 5000)
    })
}

async function getFile() {
    let file = await download()
    console.log("下载 C 完成")
    console.log("拿到 B 的链接")

    file = await download()
    console.log("下载 B 完成")
    console.log("拿到 A 的链接")

    file = await download()
    console.log("下载 A 完成")
    console.log("拿到 最终文件 的链接")

    file = await download()
    console.log("下载 A 完成")
    console.log("下载 最终文件 完成")
}

console.log("开始执行了~")
console.log("先去下个图片~")

getFile()

console.log("做其他事情去了~")

回调地狱不见了,我们只用一个函数就完成了所有的内容,代码真是太清爽了,async + await 真是太厉害了。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,444评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,421评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,036评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,363评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,460评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,502评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,511评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,280评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,736评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,014评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,190评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,848评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,531评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,159评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,411评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,067评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,078评论 2 352

推荐阅读更多精彩内容