【问题标题】:How can I return an array of promises in a then statement如何在 then 语句中返回一系列承诺
【发布时间】:2016-02-28 13:16:24
【问题描述】:

所以在过去的几个小时里,我一直在研究异步的东西并使用 Promise。我正在使用测试框架量角器,并且遇到了一些异步问题。

在这个保存函数中,我异步调用 cm.org1.all(),然后使用 then 来获取响应。我遍历响应,我需要调用 getNewElement() 到响应中的每个元素,其中也有一个异步调用,因此每个元素都返回一个承诺。

所以我有这一系列的承诺,但我不知道如何返回它。 cm.save() 的返回是 []。我需要它是 ['foo',foo',foo',foo']

下面的这段代码不起作用,但这是我目前所拥有的。

 var cm = companyManagement() {
    //whatever is initialized below is initialized up here

    this.save = function() {
        cm.saveButton.click(); 
        var elements;
        var promises = [];
        var defer = protractor.promise.defer();
        cm.org1.all(by.repeater('brand in vm.brands'))
        .then(function(response) {
            //elements is of length 4
            elements = response;
            for(var i=0; i<elements.length;i++) {
                promises.push(getNewElement(elements, i));
            }
            //defer.fulfill(promises); not correct?
        });
        return protractor.promise.all(promises); //not correct?
    };

    function getNewElement(elements, i) {
         var defer = protractor.promise.defer();
        var alias = elements[i].element(by.binding('brand.alias'));
        alias.getText().then(function(aliasText) {
            defer.fulfill('foo');
        });
        return defer.promise;
    }
}
    cm.save()
    .then(function(response){
       console.log("my new array is",response);
    });

【问题讨论】:

  • 不,我使用什么承诺,量角器或本地人并不重要。 @DominicTobias
  • 好的,您是要返回一个 promise 数组,还是在调用 save 后等待所有 promise 完成后再继续?
  • 一般来说,promise.all 返回一个promise,这个promise会被解析,当所有提供给它的promise都会被解析,试试console.log(arguments)应该是4个结果..
  • @DominicTobias 我想等待所有承诺都完成后再继续

标签: javascript asynchronous promise protractor deferred


【解决方案1】:

在测试中手动处理量角器承诺通常表明问题过于复杂。 Protractor 有多种抽象和函数式编程工具,涵盖了大部分用例。

如果您使用中继器的.column(),您只需一行即可解决它:

this.save = function() {
    cm.saveButton.click(); 
    return cm.org1.all(by.repeater('brand in vm.brands').column('brand.alias')).getText();
};

我会这样做,但如果列brand.alias 与我拥有的某个常量匹配,我希望最终能够获得元素的父级。如果我只有别名文本,我无法获取父级,如果我错了,请纠正我。

filter()map() 救援:

cm.org1.all(by.repeater('brand in vm.brands').column('brand.alias')).filter(alias) {
    return alias.getText().then(function (aliasText) {
        return aliasText === "foo";
    });
}).map(function (alias) {
    return alias.element(by.xpath("..")).getText();  // getting the parent
});

【讨论】:

  • 我会这样做,但如果列brand.alias 与我拥有的某个常量匹配,我希望最终能够获得元素的父级。如果我只有别名文本,我无法获取父级,如果我错了,请纠正我。
  • brb 我会试试这个并回复你
  • 好的,这在大多数情况下都有效!谢谢。我对父级返回的元素(by.xpath)有点困惑。它看起来不像普通的量角器元素,它看起来像这样。 jsfiddle.net/9cepxear 通常我会执行 getInnerHtml 或 getText 之类的操作,但此处未定义。我记得昨天在我做任何这些之前尝试过这个 xpath 的东西,所以我认为它与这个特定的用例无关
  • @JarlCohnson 很有趣,您能否尝试解析 save() 函数调用的结果并查看现在打印的内容(我已添加 getText() 调用)?...
  • 我想我真的不明白我是否应该只使用var x = cm.save()cm.save().then(function(ret){var x = ret;}) 来获得cm.save() 的回报。当我在原件上使用后者时(不包括 getText 的地图),它只是在终端中等待。当前者时,它会倾倒我在那个小提琴中所拥有的东西。无论如何,在 map 函数中使用getText(),它会返回Array [ 'foo-alias\nView' ]。 (foo-alias 是我的常数)。
【解决方案2】:

试试:

this.save = function() {
    cm.saveButton.click(); 
    var elements;
    var promises = [];
    var defer = protractor.promise.defer();
    return cm.org1.all(by.repeater('brand in vm.brands'))
    .then(function(response) {
        //elements is of length 4
        elements = response;
        for(var i=0; i<elements.length;i++) {
            promises.push(getNewElement(elements, i));
        }
        return protractor.promise.all(promises);
    });
};

【讨论】:

  • cm.save() 返回 undefined 因为返回在 then() 语句中
  • 你注意到我返回“cm.org1.all()”了吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-03-09
  • 2023-03-15
  • 2018-03-10
  • 1970-01-01
  • 1970-01-01
  • 2020-04-27
  • 1970-01-01
相关资源
最近更新 更多