千家信息网

怎么使用Async函数

发表于:2026-11-03 作者:千家信息网编辑
千家信息网最后更新 2026年11月03日,本篇内容介绍了"怎么使用Async函数"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!Async 函数
千家信息网最后更新 2026年11月03日怎么使用Async函数

本篇内容介绍了"怎么使用Async函数"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

Async 函数是一个非常了不起的东西,它将会在Chrome 55中得到默认支持。它允许你书写基于promise的代码,但它看起来就跟同步的代码一样,而且不会阻塞主线程。所以,它让你的异步代码看起来并没有那么"聪明"却更具有可读性。

Async 函数的代码示例:

async function myFirstAsyncFunction() {   try {     const fulfilledValue = await promise;   }   catch (rejectedValue) {     // …   } }

如果你在一个函数声明的的前面使用async关键字,那你就可以在这个函数内使用await。当你去await一个promise的时候,这个函数将会以非阻塞的方式暂停,直到promise处于settled状态。如果这个Promise返回的是成功的状态,你将会得到返回值,如果返回的是失败的状态,那失败的信息将会被抛出。
提示: 如果你对promises不熟悉,请查看我们的promises指南

示例1: 打印响应信息

假设我们想要请求一个URL然后把响应信息打印出来,下面是使用promise的示例代码:

function logFetch(url) {   return fetch(url)     .then(response => response.text())     .then(text => {       console.log(text);     }).catch(err => {       console.error('fetch failed', err);     }); }

下面用async 函数来实现同样的功能:

async function logFetch(url) {   try {     const response = await fetch(url);     console.log(await response.text());   }   catch (err) {     console.log('fetch failed', err);   } }

可以看到代码行数和上例一样,但是使用async函数的方式使得所有的回调函数都不见了!这让我们的代码非常容易阅读,特别是那些对promise不是特别熟悉的同学。

提示: 你await的任何值都是通过Promise.resolve()来传递的,所以你可以安全地使用非本地的promise.

Async 函数的返回值

不管你是否在函数内部使用了await, Async 函数总是返回一个promise 。当 async函数显示滴返回任意值时,返回的promise将会调用resolve方法, 当async函数抛出异常错误时,返回的promise将会调用reject方法,所以:

// wait ms milliseconds function wait(ms) {   return new Promise(r => setTimeout(r, ms)); }  async function hello() {   await wait(500);   return 'world'; }

当执行hello()时,返回一个成功状态,并且传递的值为world的promise.

async function foo() {   await wait(500);   throw Error('bar'); }

当执行hello()时,返回一个失败状态,并且传递的值为Error('bar')的promise.

示例2: 响应流

在更复杂点的案例中, async函数更能体现其优越性。假设我们想要在记录chunks数据时将其变成响应流, 并返回最终的信息长度。

提示: "记录chunks" 让我感觉很别扭.

下面是使用promise的方式:

function getResponseSize(url) {   return fetch(url).then(response => {     const reader = response.body.getReader();     let total = 0;      return reader.read().then(function processResult(result) {       if (result.done) return total;        const value = result.value;       total += value.length;       console.log('Received chunk', value);        return reader.read().then(processResult);     })   }); }

看清楚了,我是 promise "地下党" Jake Archibald。看到我是怎样在它内部调用 processResult 并建立异步循环的了吗?这样写让我觉得自己"很聪明"。但是正如大多数"聪明的"代码一样,你不得不盯着它看很久才能搞清楚它在做什么,就像九十年代的那些魔眼照片一样。引用

让我们用async函数来重写上面的功能:

async function getResponseSize(url) {   const response = await fetch(url);   const reader = response.body.getReader();   let result = await reader.read();   let total = 0;    while (!result.done) {     const value = result.value;     total += value.length;     console.log('Received chunk', value);     // get the next result     result = await reader.read();   }    return total; }

所有的"聪明"的代码都不见了。现在新的异步循环使用了可靠的,看起来普通的while循环来代替,这使我感觉非常的整洁。更多的是,在将来,我们将会使用async iterators,它将会使用for of循环来代替while循环,那这讲会变得更加整洁!

提示: 我对streams比较有好感。如果你对streams不太熟悉,可以看看我的指南

Async 函数的其他语法

我们已经看过了async function() {} 的使用方式,但是async关键字还可以用于其他的函数语法中。

箭头函数

// map some URLs to json-promises const jsonPromises = urls.map(async url => {   const response = await fetch(url);   return response.json(); });

提示: array.map(func)不会在乎你给的是否是async函数,它只会把它当做一个返回值是promise的普通函数。所以,第二个回调的执行并不会等待***个回调中的await处理完成。

对象方法

const storage = {   async getAvatar(name) {     const cache = await caches.open('avatars');     return cache.match(`/avatars/${name}.jpg`);   } };  storage.getAvatar('jaffathecake').then(…);

类方法

class Storage {   constructor() {     this.cachePromise = caches.open('avatars');   }    async getAvatar(name) {     const cache = await this.cachePromise;     return cache.match(`/avatars/${name}.jpg`);   } }  const storage = new Storage(); storage.getAvatar('jaffathecake').then(…);

提示: 类的 constructors和getters/settings不能是 async 函数。

注意!请避免太过强调顺序

尽管你正在写的代码看起来是同步的,但请确保你没有错失并行处理的机会。

async function series() {   await wait(500);   await wait(500);   return "done!"; }

上面的代码需要 1000ms才能完成,然而:

async function parallel() {  const wait1 = wait(500);  const wait2 = wait(500);  await wait1;  await wait2;  return "done!"; }

上面的代码只需要500ms,因为两个wait在同一时间处理了。

示例3: 顺序输出请求信息

假设我们想要获取一系列的URL响应信息,并将它们尽可能快的按正确的顺序打印出来。

深呼吸....下面就是使用promise来实现的代码:

function logInOrder(urls) {   // fetch all the URLs   const textPromises = urls.map(url => {     return fetch(url).then(response => response.text());   });    // log them in order   textPromises.reduce((chain, textPromise) => {     return chain.then(() => textPromise)       .then(text => console.log(text));   }, Promise.resolve()); }

Yeah, 这达到了目的。我正在用reduce来处理一串的promise,我太"聪明"了。这是一个如此"聪明"的代码,但我们***不要这样做。

但是,当把上面的代码转换成使用 async函数来实现时,它看起来太有顺序了,以至于会使我们很迷惑:

:-1: 不推荐 - 过于强调先后顺序

async function logInOrder(urls) {   for (const url of urls) {     const response = await fetch(url);     console.log(await response.text());   } }

看起来整洁多了,但是我的第二个请求只有在***个请求被完全处理完成之后才会发出去,以此类推。这个比上面那个promise的实例慢多了。幸好这还有一个中立的方案:

:+1: 推荐 - 很好而且并行

async function logInOrder(urls) {   // fetch all the URLs in parallel   const textPromises = urls.map(async url => {     const response = await fetch(url);     return response.text();   });    // log them in sequence   for (const textPromise of textPromises) {     console.log(await textPromise);   } }

在这个例子中,全部的url一个接一个被请求和处理,但是那个'聪明的'的reduce被标准的,普通的和更具可读性的for loop 循环取代了。

浏览器兼容性和解决方法

在我写这篇文章时,Chrome 55已经默认支持async 函数。但是在所有主流浏览器中,它还在开发中:

  • Edge - In build 14342+ behind a flag

  • Firefox - active development

  • Safari - active development

解决方法 1:Generators

所有的主流浏览器的***版本都支持generators,如果你正在使用它们,你可以稍稍polyfill一下 async函数.

Babel正可以为你做这些事情,这里有个通过Babel REPL写的示例 - 是不是感觉对转换后的代码很熟悉。这个转换机制是 Babel's es2017 preset的一部分。

提示: Babel REPL是一个很有趣的东西,试试吧。

我建议你现在就这样做,因为当你的目标浏览器支持了async函数时,你只需要将Babel从你的项目中去除即可。但是如果你真的不想使用转换工具,你可以使用Babel's polyfill点击预览。

async function slowEcho(val) {   await wait(1000);   return val; }

当你使用了上面说的polyfill点击预览,你可以将上面的代码替换为:

const slowEcho = createAsyncFunction(function*(val) {   yield wait(1000);   return val; });

注意到你通过给createAsyncFunction函数传递了一个generator (function*),然后使用yield 代替 await。除此之外它们的效果一样。

解决方法2: regenerator

如果你想要兼容旧的浏览器,Babel同样也能把generators给转换了,这样你就可以在IE8以上的浏览器中使用async函数,但你需要使用Babel的 es2017 preset和 the es2015 preset

你会看到转换后的代码并不好看,所以请小心代码膨胀。

Async all the things!

一旦所有浏览器都支持async函数了,请在所有返回值是promise的函数上使用async!因为它不仅可以使你的代码更tider, 而且它确保了async函数 总是返回一个 promise 。

"怎么使用Async函数"的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注网站,小编将为大家输出更多高质量的实用文章!

函数 代码 聪明 方法 浏览器 提示 浏览 信息 示例 处理 循环 状态 面的 顺序 支持 方式 整洁 普通 感觉 更多 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 互联网科技企业 互联网科技公司排名 云信互联网科技有限公司 金融科技与互联网金融 互联网科技公司发展 奔汉互联网科技 互联网科技博客 科技赋能互联网健康 北京大学互联网科技怎么样 恒银科技与互联网金融 阿里互联网科技公司 中国航天科技大学国际工业互联网 呼和浩特新华互联网科技学院 中国互联网十大科技股排名 迪庆互联网科技招生 互联网科技融合创新 萌小萌互联网科技河南有限公司 互联网科技企业商标注意事项 广州三三互联网科技有限公司 科技发展第三阶段互联网时代 广州紫鲸互联网科技有限公司 成都仁贤领冠互联网科技有限公司 成都玖崟互联网科技有限公司乐商圈怎么样 天速互联网络科技有限公司 互联网教育科技公司vipkid 新兴科技互联网创新大赛颁奖典礼 亳州好赞互联网科技有限公司 互联网科技资金流入 互联网与数字科技关系 互联网风格科技公司名称
0