【问题标题】:How to break when found the item?找到物品后如何破解?
【发布时间】:2015-05-26 07:58:57
【问题描述】:

我有一个网络测试代码,我不想在找到该项目后迭代其余代码。 此代码迭代到所有项目并最终返回。 如何解决这个问题,因为在每个我都不打破!

isItemPresent: function (name) {
            var def = Q.defer();
            Trace.add("Checking the " + name + " inside the menu");
            var count = 0, total = 0, stop = false;
            var listObj = element(by.id(this.MENU_ID)).all(by.tagName("div"));

            listObj.count().then(function (nr) {
                total = nr;
                listObj.each(func);
            });
            var _this = this;          
            var func = function (element) {

                element.getAttribute('class').then(function (classes) {                  
                    count++;
                    if (classes.indexOf(name) !== -1 && !stop) {
                        stop = true;                      
                        element.getAttribute('id').then(function (value) {
                            _this._isItemVisible('', value).then(function (opt) {
                                value = value.match(/(\d+)/g);                            
                                if (opt.success) {
                                   // console.log('------- BREAK --------');
                                    def.resolve({success: true, msg: {index: value[0]}});
                                    Trace.add("Menu item: " + name + " was found in the main menu.");                                  
                                } else {
                                    def.resolve({success: false, msg: {index: value[0]}});
                                    Trace.add("Menu item: " + name + " was not found in the main menu.");
                                }
                            });
                        });
                    } else if (count === total && stop === true) {
                        def.resolve({success: false, msg: {index: 0}});
      Trace.add("Menu item: " + name + " was not found in the main menu.");
                        stop = true;
                    }
                });
            };
            return def.promise;
        };

【问题讨论】:

  • 你究竟是在哪里试图停止循环?而且,listObj.each() 来自哪个库?有没有办法停止循环?你可以通过抛出一个异常来打破基于承诺的东西,承诺库将捕获并变成你可以在更高级别处理的承诺拒绝。
  • listObj 包含例如很多菜单项(1000 个),当我在第十八个中找到该项目时,然后 BREAK...
  • 我在问你listObj 是什么类型的对象以及它如何具有.each() 方法,因为这不是标准的Javascript。而且,我在问你究竟在代码中的哪个位置尝试停止循环,因为这会影响你的执行方式?如果不了解这些答案,我们将无法回答您的问题。另外,请尽量及时回复,否则人们会失去帮助的兴趣。如果您在不到几个小时内回答问题而不是等待几乎一整天,StackOverflow 的效果会好得多。

标签: javascript angularjs promise each web-testing


【解决方案1】:

有各种各样的解决方案,没有一个是特别明显的。 This is the best presentation/discussion that I know of

您可能想考虑 this answer 中给出的非常简洁的 Bluebird 解决方案,但是,坚持使用 Q,这是基于同一答案中的“循环”解决方案的解决方案。

isItemPresent: function (name) {
    var _this = this,
        listObj = element(by.id(this.MENU_ID)).all(by.tagName("div")),
        list = [];

    //Map listObj to the Array `list`, providing a convenient .reduce() method.
    //If listObj has a `.toArray()` method or `.map()` method, then use that in preference.
    listObj.each(function(element) {
        list.push(element);
    });

    // To make func() useful it must return a promise :
    // * fulfilled for success - forcing a "break"
    // * rejected for failure - allowing "continue"
    function func(element) {
        return element.getAttribute('class').then(function(classes) {
            if (classes.indexOf(name) === -1) {
                return Q.reject('class "' + name + '" not found');//"continue"
            } else {
                return element.getAttribute('id').then(function(value) {
                    _this._isItemVisible('', value).then(function(opt) {
                        if(opt.success) {
                            return Q(value.match(/(\d+)/g)[0]);//"break".
                        } else {
                            return Q.reject('class "' + name + '" not visible');//"continue"
                        }
                    });
                });
            }
        });
    };

    // Master routine
    return list.reduce(function(previous, element) {
        return previous.catch(function(error) {
            console.log(error || 'list length is zero'); //optional
            return func(element);
        });
    }, Q.reject(null)).catch(function(error) {
        return Q.reject(-1);//for example
    });
};

说明

主例程构建一个.catch() 链,其中包含一个被拒绝的承诺和:

  • 只要func() 继续返回一个被拒绝的promise,catch(...) 回调确保func() 被再次调用下一个元素。

  • 如果 func() 从未命中 opt.success,则主例程返回最后一个被拒绝的 Promise(如果 list 的长度为零,则返回种子 Promise)。

  • 如果/当func() 命中opt.success,则返回一个满足所需值的承诺,并且有效地跳过主例程的承诺链的其余部分,因为没有成功的处理程序导致它执行其他操作,并且主例程返回返回给它的已履行承诺。

最后的.catch() 只是一个例子。您可能想做一些不同的事情——无论在哪里调用isItemPresent(name),最适合处理失败的事情。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-07-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多