函数中的返回值来自promise块

时间:2016-11-24 11:55:16

标签: node.js selenium selenium-webdriver promise webdriver

我正在尝试编写一个函数(使用WebdriverJS lib),该函数遍历元素列表,检查名称并构建与该名称对应的xpath定位器。我在这里简化了xpath定位器,所以不要注意。

我面临的问题是: 1)调用此函数将返回undefined。据我了解,这是因为return语句不在位,但是: 2)将它放在同步代码通常正常工作的正确位置,对异步承诺不起作用,因此调用此函数将返回相同的undefined,但因为return语句在"驱动程序之前触发。 findElement"言。

如果我想通过调用这个函数得到createdTask变量,我应该如何在这里使用return语句?

var findCreatedTask = function() {

    var createdTask;
    driver.findElements(By.xpath("//div[@id='Tasks_Tab']")).then(function(tasks) {

        for (var index = 1; index <= tasks.length; index++) {
            driver.findElement(By.xpath("//div[@id='Tasks_Tab'][" + index + "]//div[@class='task-title']")).getText().then(function(taskTitle) {
                if (taskTitle == "testName") {
                    createdTask = "//div[@id='Tasks_Tab'][" + index + "]";
                    return createdTask;
                }
            });
        }
    });
};

3 个答案:

答案 0 :(得分:1)

您将无法从此函数返回所需的值,因为当此函数返回时,该值尚未定义。

尝试在错误的位置返回值,但尝试在错误的时间访问它时,这不是问题。

您有两个选择:您可以从此函数返回一个promise,或者此函数可以接受在值可用时调用的回调。

实施例

这未经过测试,但应该让您了解如何思考它。

无极

有承诺的版本:

public void requestWithSomeHttpHeaders() {

    RequestQueue queue = Volley.newRequestQueue(this);

    StringRequest postRequest = new StringRequest(Request.Method.POST,"http://12.211.156.201/SOWebService/Service.asmx/GetCompany",
            new Response.Listener<String>()
            {
                @Override
                public void onResponse(String response) {
                    System.out.println(response);

                }
            },
            new Response.ErrorListener()
            {
                @Override
                public void onErrorResponse(VolleyError error) {

                    System.out.println(error.toString() + "--" + error.getCause());

                    // TODO Auto-generated method stub
                    Log.d("ERROR","error => "+error.toString());
                    // definitions.setText("check your internet connection");
                    if (error instanceof TimeoutError || error instanceof NoConnectionError) {
                        System.out.println("1");
                    } else if (error instanceof AuthFailureError) {
                        System.out.println("2");
                        //TODO
                    } else if (error instanceof ServerError) {
                        System.out.println("3");
                        //TODO
                    } else if (error instanceof NetworkError) {
                        System.out.println("4");
                        //TODO
                    } else if (error instanceof ParseError) {
                        System.out.println("5");
                        //TODO
                    }
                }
            }
    )

    {
        @Override
        public Map<String, String> getHeaders() throws AuthFailureError {
            Map<String, String>  params = new HashMap<String, String>();
            params.put("Token", token);
            return params;
        }

        @Override
        protected Map<String, String> getParams() throws AuthFailureError {
            // return super.getParams();
            Map<String, String>  params = new HashMap<String, String>();
            params.put("groupName", "avd");
            params.put("userCode", "ADMIN");

            return params;
        }

    };
    queue.add(postRequest);

}

然后你用:

来调用它
var findCreatedTask = function (callback) {

    var createdTask;
    return new Promise(function (resolve, reject) {

        driver.findElements(By.xpath("//div[@id='Tasks_Tab']")).then(function(tasks) {

            for (let index = 1; index <= tasks.length && !createdTask; index++) {
                driver.findElement(By.xpath("//div[@id='Tasks_Tab'][" + index + "]//div[@class='task-title']")).getText().then(function(taskTitle) {
                    if (taskTitle == "testName") {
                        createdTask = "//div[@id='Tasks_Tab'][" + index + "]";
                        resolve(createdTask);
                    }
                });
            }
        });
    });
};

回调

带回调的版本:

findCreatedTask().then(function (createdTask) {
  // you have your createdTask here
});

然后你用:

来调用它
var findCreatedTask = function (callback) {

    var createdTask;
    driver.findElements(By.xpath("//div[@id='Tasks_Tab']")).then(function(tasks) {

        for (let index = 1; index <= tasks.length && !createdTask; index++) {
            driver.findElement(By.xpath("//div[@id='Tasks_Tab'][" + index + "]//div[@class='task-title']")).getText().then(function(taskTitle) {
                if (taskTitle == "testName") {
                    createdTask = "//div[@id='Tasks_Tab'][" + index + "]";
                    callback(null, createdTask);
                }
            });
        }
    });
};

更多信息

如果您有兴趣了解承诺和回调,您可以阅读一些解释承诺和回调如何运作的其他答案:

答案 1 :(得分:1)

在这里,我清理了一下。如果在嵌套的promise中有经验,这实际上会返回错误:

int Count2(struct node **head)
{
    printf("entered");
    struct node *temp;
    int count = 1;
    temp = (*head); // pointers to the first
    while (temp->next != *head) // direct pointer comparison
    {
        printf("entered");
        temp = temp->next; // natural linked-list exploration
        count++;
    }
    return count;
}

您使用

调用它
var findCreatedTask = function() {
  var Promise = require('bluebird');
  var createdTask;
  return driver.findElements(By.xpath("//div[@id='Tasks_Tab']"))
    .then(function(tasks) {
      return Promise.map(tasks, function(task){
        return driver.findElement(By.xpath("//div[@id='Tasks_Tab'][" + index + "]//div[@class='task-title']")).getText()
      }).then(function(taskTitles){
        for (let i = 0; i < taskTitles.length; i++){
          if(taskTitles[i] === 'testName'){
            createdTask = "//div[@id='Tasks_Tab'][" + i + "]";
            return createdTask;
          }
        }
      });
  });
};

答案 2 :(得分:1)

您可以先使用promise.map获取所有文字,然后使用indexOf获取该位置:

var map = webdriver.promise.map;

var findCreatedTask = function() {
    var elems = driver.findElements(By.xpath("//div[@id='Tasks_Tab']//div[@class='task-title']"));
    return map(elems, elem => elem.getText()).then(titles => {
      var position = titles.indexOf("testName") + 1;
      return "//div[@id='Tasks_Tab'][" + position + "]";
    });
}