如何使用函数内部的赋值变量,

时间:2014-07-29 21:28:30

标签: javascript node.js csv selenium-webdriver webdriver

我正在使用Webdriverjs。我想在函数中分配一个变量,然后使用该结果与我从csv文件中检索的一些数据进行比较。如果我想在从网页读取元素的函数中比较这两个,那么来自csv的数据的值将是数组中的最后一项。如果我想在函数外部使用函数的结果并将其与csv中的数据进行比较,那么包含函数结果(textValue)的变量(pageProductName)将是未定义的,即使我定义了变量功能之外(全局)。 如何在函数外部使用textValue的值? 要么 如何在函数中以正确的顺序从csv中获取检索到的数据? 以下是我遇到问题的代码的一部分:

reader.addListener('data', function(data){
                allEntries.push(data);
         });
reader.addListener('end', function(end)
                { var i=0;
                    console.log(allEntries.length);
                   for(var j=0; j<allEntries.length;j++)
                      {
                       ProductURLArray[i]=(BaseURL+allEntries[j]['col3']+".html");
                       ProductNameArray[i]=allEntries[j]['col2'];
            var url = ProductURLArray[i];
            var name = ProductNameArray[i];
            driver.get(url);
            driver.sleep(3000);
            driver.findElement(webdriver.By.css('.product-name h1')).getText().then(function(textValue){
                        pageProductName=textValue;
                                    });
            console.log(pageProductName);
            assert.equal(pageProductName, name);
}
});

2 个答案:

答案 0 :(得分:1)

变量赋值在一个承诺中,承诺将在未来的某个时刻解决,而不一定是在调用时。

原理与getText()调用不返回函数变量的原因相同,以及为什么必须将promise作为该值的链接。

您需要链接另一个'then'调用,以便保证在分配后操作该值。鉴于这种情况,最好使用给定值来解决承诺,而不是使用全局。

<强>更新

由于getText().then承诺,在函数退出之后的某个时间才会分配pageProductName。你的for循环也使测试变得复杂(我假设这是一个单元测试),因为所有这些承诺都需要在完成这个单一测试之前完成。

在不知道测试框架的细节的情况下,它有点棘手,但如果它提供了一个设置机制(类似于mochabefore),那么你应该将CSV读数移到那个(注意)如果该CSV包含静态测试数据,则直接在某个地方的测试中声明它以使生活更轻松)。 最后需要注意的是,您需要使用异步测试,因为您的测试将在代码完全执行(promises)之前退出。通过将done回调参数传递给每个测试来了解mocha如何做到这一点。

因此,以下是您所追求的通用代码方法,但可能不是您需要的解决方案;)

d = webdriver.promise.defer();
d.then(function(items) {
    return webdriver.promise.map(items, function(item) {
        var url = BaseURL + item['col3'] + ".html";
        var name = item['col2'];
        driver.get(url);
        return driver
            .findElement(webdriver.By.css('.product-name h1'))
            .getText()
            .then(function (text) { return webdriver.promise.fulfilled(text === name); });
    });
})
.then(function (arr) { assert.equal(arr.every(function(item) { return item === true; }), true); })
.then(function () { done(); });

var reader = // get your reader
var allEntries = [];

reader.addListener('data', function (data) { allEntries.push(); });
reader.addListener('end', function () { d.fulfill(allEntries); });

我刚刚使用了文本编辑器,因此请注意它可能需要“修复”。

上述代码的快速解释:

  • 我创建了一个承诺(尚未解决)
  • 我链接了一个承诺
    • 对传递的数组的每个元素执行测试
    • 映射函数返回一个包含您之后的比较结果的承诺
  • 我链接一个承诺,然后断言所有比较都是真的
  • 我链接一个执行异步完成回调的promise(实现将依赖于测试框架,这就是mocha的做法)
  • 注意此时尚未运行任何代码
  • 我已经添加了您的代码来读取您的输入数据,现在一旦它拥有所有数据就会解析d承诺

我希望以上内容很清楚,如果您不确定,请告诉我。

答案 1 :(得分:0)

您没有初始化变量。为了能够使用它,您必须首先初始化您的全局变量。这样的事情会有所帮助

var pageProductName = null;
driver.findElement(webdriver.By.css('.product-name h1')).getText().then(function(textValue){
         pageProductName=textValue;                      
         });
console.log(pageProductName.toString());