【问题标题】:Replace Promise code with Async code plus For loop with map() in JavaScript在 JavaScript 中用异步代码替换 Promise 代码加上用 map() 的 For 循环
【发布时间】:2017-10-24 22:32:18
【问题描述】:

以下代码可以正常工作。但是,我想将函数中间的 Promise 代码(由 cmets 表示)更改为 Async 代码,并将 for 循环替换为 map()。我该怎么做?

const main = async () => {
    try{
        const driver = await new webdriver.Builder()
            .withCapabilities(webdriver.Capabilities.chrome())
            .setLoggingPrefs(prefs)
            .forBrowser('chrome')
            .setChromeOptions(options)
            .build();

        // Start promise code
        await driver.findElements(By.css('input'))
        .then(function(elements){
            for(let i=0; i<elements.length; i++){
                elements[i].getAttribute("value")
                .then(function(val){
                    console.log(val);
                });
            }
        })
        .catch(function(error){
            console.log(error);
        });
        // End promise code

        await driver.quit();
    } catch (error) {
        console.log(error);
    }
};

main();

【问题讨论】:

  • Promise 是异步的……你已经在使用 async/await,所以不是你想改变代码来使用 async/await……所以……不能我的生活猜猜你想做什么
  • elements[i].getAttribute("value").then 好吧,这看起来很时髦!我认为elements 不是 DOM 元素数组
  • @JaromandaX 有问题的代码是硒代码,并不是说我对此一无所知,但实际上,我怀疑elements 是WebAPI 的Element。虽然我在任何地方都找不到这种方法会返回 Promise...
  • 类似var elements = await driver.findElements(By.css('input')), values = elements.map(element =&gt; element.getAttribute('value'));`
  • 不过,我仍然不明白为什么问题要求使承诺代码异步......因为承诺代码本质上是异步的

标签: javascript selenium promise async-await es6-promise


【解决方案1】:

由于您只是将信息转储到控制台,我建议:

// Start promise code
try {
  for (let element of await driver.findElements(By.css('input'))){
    console.log(await element.getAttribute("value"));
  }
} catch (error) {
  console.log(error);
}

这显示了async/await 如何很好地重新捕获命令式编程,在循环中使用let

它与您的代码的不同之处在于它按顺序列出了属性(您的依赖于getAttribute 计时)。

如果速度很重要,请在保持顺序的同时并行获取属性,如下所示:

let elements = await driver.findElements(By.css('input'));
for (let val of await Promise.all(elements.map(e => e.getAttribute("value")))) {
  console.log(val);
}

【讨论】:

  • CRice 和 jib 都对我的问题给出了正确答案。我正在向 jib 提供我的多个解决方案的答案,但我测试了 CRice 的答案,它也有效,所以我给了 CRice 竖起大拇指。谢谢!
【解决方案2】:

我猜你想用不同风格的功能相同的代码替换一些承诺代码?如果是这样,这是(可疑)压缩成两行的代码:

// Start promise code
const elements = await driver.findElements(By.css('input'));
await Promise.all(elements.map(ele => ele.getAttribute('value').then(console.log))).catch(console.log);
// End promise code

您提到您希望将基于 Promise 的代码替换为 async/await 样式的代码。一般来说,我会警告不要这样做(尽管在这种情况下我认为它有帮助),因为 async/await 无论如何都是基于承诺的(所以没有逃避它们)。学会爱上这个承诺,只有在真正让代码更干净时才使用 async/await 语法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-04-15
    • 2018-04-29
    • 2015-10-24
    • 1970-01-01
    • 1970-01-01
    • 2019-03-12
    • 2020-01-11
    相关资源
    最近更新 更多