找到物品后如何破解?

How to break when found the item?

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

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

各种解决方案,其中none尤为明显。 This is the best presentation/discussion that I know of

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

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() 继续 return 被拒绝的承诺,catch(...) 回调确保为下一个元素再次调用 func() .

  • 如果 func() 从未命中 opt.success,则主例程 return 将最后被拒绝的承诺 return 发送给它(或种子承诺如果 list 的长度为零)。

  • if/when func() 命中 opt.success,一个满足所需值的承诺被 returned 和主例程的承诺链的其余部分被有效地跳过,因为没有成功的处理程序导致它以其他方式执行,并且主例程 return 是 return 已实现的承诺。

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