依次执行基于变量数组的异步方法

时间:2018-05-13 13:25:34

标签: javascript arrays promise q

我有一系列答案。

var answers = ['Yes', 'No', 'Yes']; 

我必须在网络测验中输入这些答案,其中问题会按顺序弹出。我使用selenium驱动程序来感知问题。

我使用以下方法输入答案。

var answerQuestion = function(driver, answer) {
    var defer = q.defer();

    var elementXPath = "//*[contains(@class, 'quizAnswer’)]";
    var delay = 2000;

    return driver.waintUntilVisible(elementXPath, delay).sendKeys(answer);
};

现在我想按顺序对answers数组中的每个答案执行上述方法,因为下一个问题不会出现,直到当前问题得到解答。

这里有一个简单的foreach循环失败。

function submitAnswers(driver) {
    answers.forEach(function(answer) {
        answerQuestion(driver, answer);
    });
}

那么如何基于变量数组顺序执行异步方法。

3 个答案:

答案 0 :(得分:2)

由于selenium函数返回promises,你必须按顺序依次解析。

对于你的情况,应该做到神奇。

var answerQuestion = function(driver, answer) {
    return function() {
       var defer = q.defer();
       var elementXPath = "//*[contains(@class, 'quizAnswer’)]";
       var delay = 2000;
    return driver.waintUntilVisible(elementXPath,delay).sendKeys(answer);
};

function submitAnswers(driver) {
    return answers.reduce((previous, answer) => {
                return previous.then(answerQuestion(driver, answer);
            }, Promise.resolve());
}

答案 1 :(得分:1)

起初answerQuestion应该很有希望:

function answerQuestion(driver, answer) {
 var elementXPath = "//*[contains(@class, 'quizAnswer’)]";
 var delay = 2000;

 return driver.waintUntilVisible(elementXPath, delay).sendKeys(answer);
}

然后很容易:

function submitAnswers(driver, position = 0) {
    if(position >= answers.length) return;

    return answerQuestion(answers[position]).then(function() {
      return submitAnswers(driver, position + 1);
    });
 }

或者,如果您可以使用async / await

async function submitAnswers(driver, answers) {
  for(const answer of answers)
     await answerQuestion(answer);
 }

答案 2 :(得分:-1)

我最终想出了一个方法。归功于Dave Ceddia

var answers = ['Yes', 'No', 'Yes'];

var answerQuestion = function(driver, answer) {
    var elementXPath = "//*[contains(@class, 'quizAnswer’)]";
    return driver.waintUntilVisible(elementXPath, delay).sendKeys(answer);
};

function submitAnswers(driver) {

    var chain = q.when();

    answers.forEach(function(answer) {
        chain = chain.then(function() {
            return answerQuestion(driver, answer);
        });
    });
}