在 IIFE 中编写所有异步代码是否有任何缺点或副作用?

爱德华·坦圭

我已经迷上了使用 Promise 的 async/await 语法,因为它看起来和行为都像同步代码。

尽管我看到大多数带有命名函数的 async/await 示例,但我发现我现在总是在 IIFE 中编写 async/await 代码,因为无论如何它只是语法糖,如下所示:

btnInOrderElem.onclick = () => {
    (async () => {
        contentElem.innerHTML = '';
        loaderAreaElem.style.display = 'inline';
        addLi(await loader.getData());
        addLi(await loader.getData());
        addLi(await loader.getData());
        loaderAreaElem.style.display = 'none';
    })();
}

这种做法有什么我遗漏的吗?在某些时候这样做有什么缺点吗?是否有任何理由创建命名函数以运行 async/await 代码?

斯科蒂·贾米森

在您的具体示例中,这些之间确实没有区别:

btnInOrderElem.onclick = async () => { ... }

btnInOrderElem.onclick = () => {
  (async () => { ... })()
}

async function onClickHandler() { ... }
btnInOrderElem.onclick = onClickHandler

当您将函数定义为 async 时,这意味着 Javascript 将自动导致该函数始终返回一个承诺,该承诺在其内部任务完成时解决。尽管上述代码片段中的函数定义不同(有些会返回承诺,有些会返回未定义),但实际程序的行为将相同,因为浏览器会忽略从事件处理程序返回的任何内容(通常)。

但是,如果您正在编写这样的实用程序函数:

function getUser() {
  (async () => { ... })()
}
// or
async function getUser() { ... }

这里一个重要的区别。第二个函数将返回一个承诺,因此您可以等待该承诺并获得结果值。第一个函数将调度一个异步操作,然后返回 undefined。您无法从第一个中获得结果值,也无法等待它。


这是一个给你的练习。

const wait = ms => new Promise(resolve => setTimeout(resolve, ms))

async function waitThenLog(ms, message) {
  await wait(ms)
  console.log(message)
}

;(async function main() {
  await waitThenLog(500, 'Hello World!')
  console.log('done')
})()

上面我有一个简单的程序。它将等待 500 毫秒,然后记录一条消息,然后记录“完成”。尝试更改它,以便 waitThenLog() 函数使用您的 IIFE 想法,看看您是否可以让它工作。你会发现你会遇到一些基本的问题。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章