【问题标题】:Are there any disadvantages or side-effects to writing all async code in IIFEs? [closed]在 IIFE 中编写所有异步代码是否有任何缺点或副作用? [关闭]
【发布时间】:2021-08-28 05:49:26
【问题描述】:

我已经迷上了使用 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 代码?

【问题讨论】:

  • 我看到的唯一问题是您没有使用 addEventListener。 ;) 这是对最佳实践的个人意见。
  • 你为什么不直接传递一个异步回调呢? (并使用 addEventListener ;))我打赌你不会将同步函数调用为包装好的 IIFE const log = () => {(()=>console.log('IIFE?'))();}
  • @epascarello 如果需要,我会使用 addEventListener,例如如果我必须通过{ once: true },但如果不是,我发现onclick 语法更简洁且更易于阅读。
  • 您是否有理由使用 IIFE 而不是 btnInOrderElem.onclick = async () => { ... }
  • @EdwardTanguay 我不确定我是否理解正确。对于btnInOrderElem.onclick = async () => { ... },括号内的代码 (...) 仅在用户每次单击按钮时执行。如果我没记错的话,这应该和你的例子一样

标签: javascript async-await es6-promise


【解决方案1】:

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

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

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

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

当您将函数定义为异步时,这意味着 Javascript 将自动使该函数始终返回一个 Promise,该 Promise 会在其内部任务完成时解析。虽然上述代码 sn-ps 中的函数定义不同(有些会返回 promise,而有些会返回 undefined),但实际程序的行为是相同的,因为浏览器会忽略从事件处理程序返回的任何内容(通常)。

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

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

有一个重要的区别。第二个函数将返回一个 Promise,因此您可以等待该 Promise 并获取结果值。第一个函数将调度一个异步操作,然后返回 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 想法,看看您是否可以让它工作。你会发现你会遇到一些基本问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-06-03
    • 2011-02-10
    • 2019-06-08
    • 2018-09-05
    • 2018-11-28
    • 2018-05-23
    • 2010-09-17
    • 2010-10-03
    相关资源
    最近更新 更多