AngularJS将变量传递给循环异步回调

时间:2017-01-16 17:43:45

标签: javascript angularjs angular-promise

我有一个函数在不确定数量的项目中循环,并对每个项目进行异步调用以获取其他数据(html模板文件的内容)。回调做了一些检查。结果函数应该是可以的。 $ q是先前注入的,此代码是工厂的一部分。

function searchHelpTopics(topics, searchPhrase) {
    if (topics == null || topics.length == 0) return "No search results";
    var results = [];
    var promises = [];
    for (var i = 0; i < topics.length; i++) {
        var templateURL = topics[i].URL;
        var topic = topics[i];
        if (topics[i].HelpTopicId != "Search") {
            var promise = $templateRequest(templateURL).then(function (template) {
                var text = HTMLToText(template, true);
                // do the search
                if (text.indexOf(searchPhrase) > -1) {
                    if (text.length > 50) text = text.substring(0, 50);
                    var result = {};
                    result.title = topic.Title;
                    result.excerpt = text;
                    result.helpID = topic.HelpTopicID;
                    results.push(result);
                }
            });
            promises.push(promise);
        }
    }
    return $q.all(promises).then(function () {
        return results;
    })

这里的问题是for循环不会明显等待回调,因此回调使用的主题不正确。我需要一种方法将主题传递给每个循环的回调。

2 个答案:

答案 0 :(得分:1)

因为JS只有函数作用域,所以你可以重写你的代码来使用函数而不是'for'循环(通常更好)。

要做到这一点,你可以使用JS内置的forEach(从版本1.6开始,几乎适用于所有浏览器)或者良好的功能样式库,如underscore.js或lodash.js。

甚至更好 - 使用Array.map和Array.filter - 请参阅代码

function processTemplate(topic, template) {
  var text = HTMLToText(template, true);
  // do the search
  if (text.indexOf(searchPhrase) < 0) {
    return;
  }
  if (text.length > 50) {
    text = text.substring(0, 50);
  }
  return {
    title: topic.Title,
    excerpt: text,
    helpID: topic.HelpTopicID
  };
}

function searchHelpTopics(topics, searchPhrase) {
  if (!topics || topics.length === 0) {
    return "No search results";
  }
  var promises = topics
    .filter(function(topic) { return topic.HelpTopicId !== "Search"; })
    .map(function(topic) {
      return $templateRequest(topic.URL).then(processTemplate);
    });
  return $q.all(promises)
    .then(function (results) {
      return results.filter(function (result) {
        return result; // filters out 'undefined'
      });
    });
}

答案 1 :(得分:0)

这不是一个完整的解决方案,但足以表明它是如何运作的

somefactory.getHelpTopics().then(function (topics) {
    somefactory.searchHelpTopics(topics, searchText).then(function (searchResults) {
        vm.searchResults = searchResults;
        vm.helpID = "Search";
    });
});

--- some factory functions ----
function searchHelpTopics(topics, searchPhrase) {
    if (!topics || topics.length === 0) return "No search results";
    var promises = topics
        .filter(function (topic) { return topic.HelpTopicId !== "Search"; })
        .map(function (topic) {
            return $templateRequest(topic.URL).then(function (template) {
                return searchHelpTemplate(template, topic, searchPhrase);
            });
        });
    return $q.all(promises).then(function (results) {
        return results.filter(function (result) {
            return result; // filters out 'undefined'
        });
    });
}
function searchHelpTemplate(template, topic, searchPhrase) {
    var text = HTMLToText(template, true);
    // do the search
    if (text.indexOf(searchPhrase) < 0 && topic.Title.indexOf(searchPhrase) < 0) {
        return;
    }
    if (text.length > 50) {
        text = text.substring(0, 50);
    }
    return {
        title: topic.Title,
        excerpt: text,
        helpID: topic.HelpTopicId
    };
}