如何从“then”链中的最后一个promise返回函数中的promise

时间:2015-09-14 13:03:37

标签: javascript selenium return promise

我正在使用Selenium和JavaScript编写测试。我是新手,也是功能编程和承诺的新手。我正在尝试创建一个需要做三件事的功能:

  1. 点击输入
  2. 清除输入
  3. SendKeys输入
  4. 我当前的功能不起作用:

        var clearAndSendKeys = function(driver, elementIdentifier, sendKeys) {
            var returnValue;
            driver.findElement(elementIdentifier).then(function(inputField){
                inputField.click().then(function() {
                    inputField.clear().then(function() {
                        returnValue = inputField.sendKeys(sendKeys);
                    });                 
                });                 
            });
            return returnValue;
        }
    

    然后将调用该函数,例如:

        clearAndSendKeys(driver, webdriver.By.id('date_field'), '14.09.2015').then(function(){
            //Do stuff
        });
    

    我希望变量returnValue包含来自sendKeys的承诺。但是,函数clearAndSendKeys在运行sendKeys之前返回未定义的变量。我假设这是因为returnValue从未被定义为承诺,因此程序不知道它需要等待sendKeys

    如何让我的函数clearAndSendKeyssendKeys返回承诺?我宁愿避免向clearAndSendKeys函数添加回调。

    修改:从代码中删除.then({return data}),因为这是一个错字。

2 个答案:

答案 0 :(得分:4)

您必须从.then回调中返回每个承诺:

var clearAndSendKeys = function(driver, elementIdentifier, sendKeys) {
    return driver.findElement(elementIdentifier).then(function(inputField){
        return inputField.click().then(function() {
            return inputField.clear().then(function() {
                return inputField.sendKeys(sendKeys);
            });                 
        });                 
    });
}

.then返回的承诺将解析为与回调返回的值相同的值。

请参阅Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference了解您当前代码无效的原因。承诺是异步

答案 1 :(得分:4)

首先,它可能不是最好的想法来嵌套承诺,完全打败它们消除回调地狱的主要目的。 then回调可以返回Thenable对象,该对象允许创建漂亮的异步操作链。

在这种情况下,您只需要存储对主函数范围内第一个异步操作的结果可用的输入字段的引用,然后创建可以从此函数返回的异步操作链。

var clearAndSendKeys = function(driver, elementIdentifier, sendKeys) {
    var inputFieldRef;
    return driver.findElement(elementIdentifier)
        .then(function(inputField){
            inputFieldRef = inputField;
            return inputField.click();
        }).then(function() {
            return inputFieldRef.clear();
        }).then(function() {
            return inputFieldRef.sendKeys(sendKeys);
        });
}