Return value in function from a promise block

后端 未结 3 1846
小蘑菇
小蘑菇 2020-11-29 13:55

I\'m trying to write a function (using WebdriverJS lib) that iterates through a list of elements, checks the names and build an xpath locator that corresponds to that name.

相关标签:
3条回答
  • 2020-11-29 14:17

    Here you go, I cleaned it up a bit. This will actually return an error if one is experienced in the nested promises:

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

    You call it using

    findCreatedTask.then(function(res){
       //do your thing
    }).catch(function(err){
       console.error(err.stack);
    });
    
    0 讨论(0)
  • 2020-11-29 14:19

    You could first get all the texts with promise.map and then get the position with 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 + "]";
        });
    }
    
    0 讨论(0)
  • 2020-11-29 14:37

    You will not be able to return the value that you want from this function because when this function returns, the value is not defined yet.

    This is not a problem that you try to return the value in the wrong place, but that you try to access it at the wrong time.

    You have two options: you can either return a promise from this function, or this function can take a callback that would be called when the value is available.

    Examples

    This is not tested but should give you an idea on how to think about it.

    Promise

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

    and then you call it with:

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

    Callback

    Version with callback:

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

    and then you call it with:

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

    More info

    You can read some other answers that explain how promises and callbacks work if you're interested to know ore about it:

    • A detailed explanation on how to use callbacks and promises
    • Explanation on how to use promises in complex request handlers
    • An explanation of what a promise really is, on the example of AJAX requests
    • An explanation of callbacks, promises and how to access data returned asynchronously
    0 讨论(0)
提交回复
热议问题