【问题标题】:Intern: loop on Promise.<Array.<leadfoot/Element>>实习生:循环 Promise.<Array.<leadfoot/Element>>
【发布时间】:2015-11-23 04:57:38
【问题描述】:

为了简单起见,假设我有以下 DOM 结构:

<div class='myparent'>
    <div class='child'>
        <div class="label">A</div>
        <div class="ico"/>
    </div>
    <div class='child'>
        <div class="label">B</div>
        <div class="ico"/>
    </div>
    <div class='child'>
        <div class="label">C</div>
        <div class="ico"/>
    </div>
</div>

我想在函数 findAllByCssSelector('.child') 返回的所有 child 元素中循环。特别是,只有当 div 的 label 是 B 时,我才会点击 ico div 子元素。

我记得,findAllByCssSelector() 返回Promise.&lt;Array.&lt;leadfoot/Element&gt;&gt;

通常我应该这样做:

var my_label = null;
this.remote
  .findAllByCssSelector('.my-selector').then(function (elementArray) {
      for(.....) {
        elementArray[i]
            .getVisibileText()
              .then(function (text) {
                  if(text == my_label)
                    elementArray[i].findByCssSelector('.ico').click().end()
              }
      }
})

我尝试了这段代码但没有成功,因为getVisibleText().then() 函数中的elementArray[i] 不存在 - 就像我失去了它的引用一样。此外,我还需要如果在循环结束时没有找到标签,则应该抛出异常。

我怎样才能做到这一点?有人可以帮忙吗?

【问题讨论】:

  • 所以?只需将循环放在 Promise 回调中。你知道如何访问数组吗?请发布您当前的代码尝试(即使不工作)

标签: javascript promise this intern leadfoot


【解决方案1】:

最简单的方法是使用 Xpath 表达式直接选择项目,例如:

.findByXpath('//div[@class="child" and div[@class="label" and text()="B"]]/div[@class="ico"]')

上面的表达式将找到第一个具有类“ico”的 div,它是具有类“child”的 div 的子级,该 div 具有一个具有类“label”和文本内容“B”的子 div。


更新

使用 Xpath 表达式几乎总是比使用 Leadfoot 命令循环遍历元素更可取,因为它的效率要高得多,但如果出于某种原因需要循环,您可以执行以下操作:

var my_label = null;
this.remote
    .findAllByCssSelector('.my-selector')
    .then(function (elementArray) {
        return Promise.all(elementArray.map(function (element) {
            return element.getVisibleText()
                .then(function (text) {
                    if (text === my_label) {
                        return element.findByCssSelector('.ico')
                            .then(function (ico) {
                                return ico.click();
                            });
                    }
                });
        });
    });

需要注意的几个关键点:

  1. 当您在 then 回调中执行异步操作时,您需要从 then 回调中返回 Promises/Commands
  2. 元素方法(如element.findByCssSelector)返回Promises,而不是Commands,因此您不能在结果上调用click

【讨论】:

  • 不幸的是,icolabel div 是兄弟,如上所示。此外,我会说上面的 sn-p 确实被简化了,因为childlabe|ico 之间可能有更多的 div。不过感谢您的努力。顺便说一句,这里的问题是如何循环到Promise.&lt;Array.&lt;leadfoot/Element&gt;&gt;,并在验证某个条件时跟踪元素。我更新了第一篇文章以更好地解释我自己。
  • 上面的 Xpath 语句假定 icolabel div 是同级的——这就是重点。它与问题中提供的 sn-p 一起使用,并且可以轻松修改以处理更复杂的结构。
  • @jason0x43 抱歉,在我编辑我的答案以使用 map 后,没有正确回答你的答案,因此删除了我的答案:)
  • 坦克杰森!在故事的最后,我使用了 xpath 选择器,它更简单,而且我的代码仍然可读 :) 谢谢!但是,我会继续考虑 Promise 数组循环,以备将来使用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多