【问题标题】:How to avoid await hell in javascript如何避免在javascript中等待地狱
【发布时间】:2019-07-26 00:09:37
【问题描述】:

我正在尝试使用 puppeteer api,但我发现我经常需要使用 await 关键字。

例如

let title = await (await (await page
                .$("#someId"))
                .$x(".."))[0]
                .$eval("span:first-child", el=>el.innerText);

如果返回的对象没有承诺 API 可以像这样轻松链接:

let title = page
            .$("#someId")
            .$x("..")[0]
            .$eval("span:first-child", el=>el.innerText);

是否有任何库可以解决此问题,例如通过代理返回的对象?

例如我想到的一个可能的用法是:

let title = await awaitProxy(page)
            .$("#someId")
            .$x("..")[0]
            .$eval("span:first-child", el=>el.innerText)
            .awaitProxyValue();

【问题讨论】:

  • 不,代码是异步的,你必须处理它。至少你不必使用回调!似乎你有一半的问题是你试图在一行代码上做很多事情。如果您只是将其拆分,则阅读起来会容易得多
  • @Liam 我必须管理,热量比回调地狱少:)。但是,如果我将其拆分,我将需要无缘无故地使用大量中间变量。

标签: javascript ecmascript-6 async-await puppeteer chain


【解决方案1】:

可能有一个库可以更优雅地包装 Promise 和 await,但通常我混合搭配 Promises 和 async/await 以使代码更具可读性。
例如,在您的示例中,它会有点像这样:

let title = await page.$("#introduction")
  .then(intro => intro.$x(".."))
  .then(results => results[0])
  .then(first => first.$eval("span:first-child", el => el.innerText));

这样,await 仅用于将值拆箱一次。

【讨论】:

  • 或者直接使用const intro = await intro.$x("..");
  • @Liam True。在此过程中您会获得更多变量,但 IMO 使代码更易于维护。
猜你喜欢
  • 2020-02-11
  • 2021-01-31
  • 1970-01-01
  • 2017-05-08
  • 1970-01-01
  • 2021-06-21
  • 2020-10-15
  • 2017-08-18
  • 2011-03-20
相关资源
最近更新 更多