找到物品时如何打破?

时间:2015-05-26 07:58:58

标签: javascript angularjs promise each web-testing

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

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

1 个答案:

答案 0 :(得分: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()继续返回被拒绝的承诺,catch(...)回调就会确保再次为下一个元素调用func()

  • 如果func()永远不会命中opt.success,则主例程返回返回给它的最后一个被拒绝的承诺(如果list长度为零,则返回种子承诺)。

  • 如果/当func()点击opt.success时,会返回一个履行了所需值的承诺,并且有效跳过主例程的承诺链的其余部分,因为没有成功处理程序导致它不这样做,并且主例程返回返回给它的已履行的承诺。

最终.catch()只是一个例子。您可能希望做一些不同的事情 - 无论何处调用isItemPresent(name),最适合处理失败的事情。