如何在JavaScript对象字面量中声明异步函数
如何在JavaScript对象字面量中声明异步函数
你问的这个问题很常见,尤其是刚接触async/await的开发者经常会碰到。其实在对象字面量里声明异步函数有两种很直观的写法,我直接结合你的代码给你改造,顺便解决你调用时可能遇到的异步时序问题:
写法一:给传统函数声明添加async关键字
直接在原来的function关键字前加上async,就能把它变成异步函数,然后内部就可以用await替代原来的then链了:
var QMEM = QMEM || { config: null, loadConfig: async function(url) { console.log('url = ', url); try { // 用await等待fetch请求完成 const res = await fetch(url); // 再等待响应体解析为JSON this.config = await res.json(); } catch (err) { // 统一捕获错误 console.log(err); } }, logConfig: function() { console.log('current configuration:\n', this.config); } };
写法二:用对象方法简写语法(更推荐)
ES6之后支持更简洁的对象方法写法,直接在方法名前加async就行,代码看起来更清爽:
var QMEM = QMEM || { config: null, // 简写的异步方法 async loadConfig(url) { console.log('url = ', url); try { const res = await fetch(url); this.config = await res.json(); } catch (err) { console.log(err); } }, // 普通方法也可以用简写形式 logConfig() { console.log('current configuration:\n', this.config); } };
重要提醒:处理异步调用的时序问题
你原来的调用方式会有问题——因为loadConfig现在是异步函数,它会在后台加载资源,而你的logConfig会立刻执行,这时候config还没被赋值,依然是null。所以必须等loadConfig执行完成后再调用logConfig,有两种常用方式:
- 在
async函数里用await等待:
// 封装一个初始化函数 async function initQMEM() { await QMEM.loadConfig(myConfigUrl); // 等待加载完成后再打印配置 QMEM.logConfig(); } // 执行初始化 initQMEM();
- 用Promise的
.then链式调用:
QMEM.loadConfig(myConfigUrl).then(() => { // 加载完成后触发logConfig QMEM.logConfig(); });
避坑提示
千万别用箭头函数来声明这个异步方法!因为箭头函数的this不会绑定到QMEM对象本身,而是继承自外层作用域的this,这样this.config = await res.json()就会给错误的对象赋值,导致你的QMEM.config永远不会被正确设置。
内容来源于stack exchange
相关产品推荐
相关产品推荐

