【问题标题】:how to print array in javascript that has element pushed to it asynchronously?如何在javascript中打印元素异步推送到它的数组?
【发布时间】:2019-05-21 22:48:41
【问题描述】:

我正在使用量角器为非角度应用程序开发端到端 UI 测试用例。我在网页上呈现的 UL 标记内有一堆 LI 标记。我需要获取所有 LI 标记的值并将它们存储在一个数组中,然后检查该数组是否已排序。

checkResultList() {
        // element locator for UL
        const listResult = element(by.xpath('//*[@id="flightModuleList"]'));
        browser.wait(EC.visibilityOf(this.listResult), 60000);

        // Get All the LIs as ElementArrayFinder
        let items = listResult.all(by.xpath('//li//div[@class="uitk-col all-col-shrink"]//div[contains(@class,"primary-content")]//span[contains(@class, "full-bold")]'));

        let prices = [];
        items.each(function(ele, index) {
            ele.getText().then(function(text) {

                // get floating point numbers from string
                const price = text.match(/[+-]?\d+(\.\d+)?/g).map(function(v) {

                    prices.push(parseFloat(v));
                    return parseFloat(v);
                });

            })
        })

        expect(prices.length).toBe(80); // prints 0

    }

我希望在检查价格数组的长度之前推送所有值。

【问题讨论】:

  • 为什么不使用setInterval直到长度达到预期?
  • @Janak 请注意您已经设置了两次let prices = [];!第一个是多余的
  • @Mulli 因为使用 setInterval 进行轮询是一个可怕的想法,而您只能使用 Promise

标签: javascript async-await jasmine protractor ui-testing


【解决方案1】:

这里有一个例子可以给你一些启发。下面的代码首先等待项目文本,然后从文本中获取任何数字。然后它等待所有项目都解决,然后将数组(使用reduce)展平一层。

// mock for items
class Item {
  constructor(value) {
    this.value = value;
  }
  
  getText() {
    return Promise.resolve(this.value);
  }
}

let items = ["foo", "bar +12.54", "baz -1.29", "1.23 4.56"]
  .map(str => new Item(str));

// answer
(async function () {
  let prices = items.map(async item => {
    let text = await item.getText();
    let prices = text.match(/[+-]?\d+(\.\d+)?/g) || [];
    return prices.map(parseFloat);
  });
  
  prices = await Promise.all(prices);
  prices = prices.reduce((acc, arr) => acc.concat(arr));

  console.log(prices);
})();

或者,您可以通过首先等待所有结果来进一步简化此操作。但是,由于正则表达式匹配和浮点解析对于我选择 not 来执行此操作的每个项目都是独立的。上面的代码将在 Promise 解析后立即将正则表达式与字符串匹配,而不是等待所有 Promise 解析然后将每个元素与正则表达式匹配(如下所示)。

用于此的代码(更紧凑,不太优化)是:

(async function () {
  let texts = await Promise.all(items.map(item => item.getText()));
  let prices = texts
    .map(text => text.match(/[+-]?\d+(\.\d+)?/g) || [])
    .reduce((acc, arr) => acc.concat(arr))
    .map(parseFloat);
  console.log(prices);
})();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-12-11
    • 1970-01-01
    • 1970-01-01
    • 2021-11-06
    • 1970-01-01
    • 2015-09-24
    • 2015-08-19
    • 1970-01-01
    相关资源
    最近更新 更多