从promise块返回函数中的值

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

我在这里遇到的问题是:1)调用这个函数返回undefined。 据我所知,这是因为return语句不在其位置上,但是:2)将它放在正确的地方,同步代码通常工作,不适用于异步promise,因此调用此函数将返回同样未定义,但是因为return语句在“driver.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;
                }
            });
        }
    });
};

您可以先用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 + "]";
    });
}

在这里,我把它清理了一下。 如果有人遇到嵌套的promise,这实际上会返回一个错误:

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;
          }
        }
      });
  });
};

你用它来称呼它

findCreatedTask.then(function(res){
   //do your thing
}).catch(function(err){
   console.error(err.stack);
});

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

这不是你尝试在错误的地方返回值的问题,而是你尝试在错误的时间访问它的问题。

你有两种选择:你可以从这个函数返回一个promise,或者这个函数可以接受一个回调函数,当这个值可用时会被调用。

例子

这没有经过测试,但应该给你一个关于如何思考的想法。

诺言

有承诺的版本:

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);
                }
            });
        }
    });
};

然后你用以下方式调用它:

findCreatedTask(function (err, createdTask) {
  // you have your createdTask here
});

更多信息

您可以阅读其他一些解释承诺和回调如何工作的答案,如果您有兴趣知道其中的内容:

  • 有关如何使用回调和承诺的详细说明
  • 有关如何在复杂的请求处理程序中使用promise的说明
  • 关于AJAX请求的例子,解释了什么是承诺
  • 解释回调,承诺以及如何访问异步返回的数据
  • 链接地址: http://www.djcxy.com/p/55357.html

    上一篇: Return value in function from a promise block

    下一篇: What is wrong with promise resolving?