如何在javascript中打印元素异步推送到它的数组?

Posted

技术标签:

【中文标题】如何在javascript中打印元素异步推送到它的数组?【英文标题】:how to print array in javascript that has element pushed to it asynchronously? 【发布时间】: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

    

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

【问题讨论】:

protractortest.org/#/async-await ??? 为什么不使用setInterval直到长度达到预期? @Janak 请注意您已经设置了两次let prices = [];!第一个是多余的 @Mulli 因为使用 setInterval 进行轮询是一个可怕的想法,而您只能使用 Promise 【参考方案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);
)();

【讨论】:

以上是关于如何在javascript中打印元素异步推送到它的数组?的主要内容,如果未能解决你的问题,请参考以下文章

无法弄清楚如何将数据异步推送到数组

如何将 GraphQL 中的对象元素推送到 javascript 对象中的嵌套数组中?

如何在 MySQL 中将元素推送到 JSON

在javascript中将新元素推送到数组时出错

如何正确地将具有多个元素的新对象推送到数组中?

Javascript - 为啥从函数返回 array.push(x) 不会将元素 x 推送到数组中?