【发布时间】:2020-05-22 07:02:51
【问题描述】:
我有一个特定的情况,我正在循环多个工件并基于一组规则(在 JSON 中)我必须评估它们中的每一个,因为检查每个规则的调用是异步的,我使用了 Promise .all 在评估所有规则后执行一些最后的步骤。
下面的代码用于根据一个工件的规则类型评估规则。
Const promises=[];
var ruleTest = function (artifact) {
main.totalLength++;
var config = RuleEngine.RuleConfigurations;
// fetching rules and iterating through each of them to call has_attribute function or contains function based on the Type in the JSON config
for (let i = 0; i < config.length; i++) {
console.log(config[i]);
switch (config[i].Rule.Type) {
case "has_Attribute":
has_Attribute(artifact, config[i]);
break;
case "contains":
contains(artifact, config[i]);
break;
}
}
Promise.all(promises).then(values => {
console.log(values);
console.log(main.contentList)
// some final steps after all the promise are resolved
main.loading = false;
main.displayInfo = true;
main.showInfo = true;
//issuesFlag=false;
})
}
function has_Attribute(artifact, rule) {
var attributes = rule.Rule.MandatoryAttributes.split(',');
for (let i = 0; i < attributes.length; i++) {
attributes[i] = attributes[i].trim();
}
promises.push(hasAttributePromise(artifact, rule, attributes));
}
var hasAttributePromise = function (artifact, rule, attributes) {
return new Promise((resolve, reject) => {
// some async stuff
resolve(value);
}
}
function contains(artifact, rule) {
//some business logic
promises.push(containsPromise(artifact, rule, blackListWords, whiteListWords))
}
var containsPromise = function (artifact, rule, blackListWords, whiteListWords) {
return new Promise((resolve) => {
//some async stuff
resolve(value);
}
}
我面临的问题是即使有两个规则(每种类型一个),脚本甚至在调用第二个 promise 之前就退出并且页面似乎卡住了 promise.all 从未被调用。我必须为多个规则实现这一点,并且会根据规则类型多次创建相同的承诺。
奇怪的是,如果我使用变量名创建承诺而不是从函数返回它,并且我通过 promise.all 中的变量名调用它,它每次调用都会工作一次然后退出。 例如:
var ruleTest = function (artifact) {
main.totalLength++;
RuleEngine.RuleConfigurations.forEach(function (rule) {
console.log(rule)
switch (rule.Rule.Type) {
case "has_Attribute":
has_Attribute(artifact, rule);
break;
case "contains":
contains(artifact, rule);
break;
}
})
Promise.all([hasAttributePromise, containsPromise]).then(values => {
console.log(values);
console.log(main.contentList)
if (issuesFlag){
main.updatedLength++;
}
main.loading = false;
main.displayInfo = true;
main.showInfo = true;
issuesFlag=false;
})
}
function has_Attribute(artifact, rule) {
var attributes = rule.Rule.MandatoryAttributes.split(',');
for(var i=0; i<attributes.length; i++){
attributes[i]=attributes[i].trim();
}
hasAttributePromise = new Promise((resolve, reject) => {
asyncCall(()=>{
//business logic
resolve();
})
});
}
我也尝试使用 forEach 代替 for 循环,但没有帮助。
我是 Javascript 的新手,我无法指出问题所在,所以即使这是一个愚蠢的错误,也请在这里帮助我。
【问题讨论】:
-
I cannot reproduce it。我填写了一些缺失的配置并修复了一些语法错误以到达那里 - 这是我能做的最好的。我假设语法错误来自在这里转录代码。这应该工作。如果没有,那么所提供的代码并不是真正的问题。你能提供一个显示行为的minimal reproducible example 吗?
-
堆叠闪电战会有所帮助
-
@RaphaelSt 它总是比use the stack snippet feature 更可取,并在此处复制它。这使得问题是独立的,不依赖于外部资源 - 如果该链接断开,未来的访问者和潜在的回答者将无法从中受益。
-
//some business logic是什么contains,你确定不是异步的吗? -
你不应该使用全局
promises数组!在ruleTest和return中本地声明它来自contains和hasAttribute的承诺,而不是改变全局。
标签: javascript loops asynchronous promise