javascript - 迭代通常适用于 Map()、Set().. 但会违反承诺
问题描述
步骤提供重现..
const map = new Map()
let success = new Set()
let failed = new Set()
map.set('success', success)
map.set('failed', failed)
success.add(123)
failed.add(55)
success.add(456)
var iter = map.entries()
console.log(
'printing map output ==> ',
map,
'map.entries() ==> ',
map.entries(),
'iter.next().value ==> ',
iter.next().value,
'iter.next().value ==> ',
iter.next().value
)
for (const [key, value] of map.entries()) {
for (const val of value) {
console.log(key, val)
}
}
上面的代码输出我以下预期的结果..
所以现在,我使用同样的代码和一个 promise,
$(button).submit(updateTags(enteredTags, tagName,contentIDs).then(
(resultMap) => {
console.log("result after promise ==> ", resultMap); // I get proper output here, please see the below image for this
for (const [key, value] of resultMap.entries()) {
for (const val of value) {
console.log("key ==> ", key,"value ==> ", val)// I don't get all the results here.. I am hurting my head with this, did I do any mistake ?
}
}
}));
let updateTags = (newTags, tagName, contentIds) => {
let deferred = Q.defer(),
resultMap = new Map(),
success_ids = [],
failed_ids = [],
counter = 1;
resultMap.set("success", success_ids);
resultMap.set("failed", failed_ids);
contentIds.forEach(function (contentId) {
var tags = [];
osapi.jive.core.get({
v: "v3",
href: "/contents/" + contentId + ""
}).execute(function (content) {
tags = content.tags;
content["tags"] = _.union(tags, newTags);
osapi.jive.core.put({
v: "v3",
href: "/contents/" + contentId + "",
body: content
}).execute(function (response) {
if (response.error) {
failed_ids.push(contentId);
} else {
success_ids.push(contentId);
}
if (counter === contentIds.length) {
deferred.resolve(resultMap);
$("#spinner").hide()
}
counter++;
deferred.resolve(resultMap);
}, function (error) {
failed_ids.push(contentId);
if (counter === contentIds.length) {
deferred.resolve(resultMap);
$("#spinner").hide()
}
counter++;
}
);
})
});
return deferred.promise;
};
最后,第二个代码片段“with promise”应该显示如下结果:
我现在已经添加了我的所有代码,promise 只解析一次,我得到 resultMap 来检查成功和失败的 ID。我想迭代它们以再次将它们转储到记录器中。
解决方案
在您问题中当前的代码中,您过早地解决了承诺:
let updateTags = (newTags, tagName, contentIds) => {
//... removed some code that does not show where you go wrong
contentIds.forEach(function (contentId) {
osapi.jive.core.get()
.execute(function (content) {
}).execute(function (response) {
if (response.error) {
failed_ids.push(contentId);
} else {
success_ids.push(contentId);
}
if (counter === contentIds.length) {
deferred.resolve(resultMap);
$("#spinner").hide()
}
counter++;
//here you are always resolving the promise
deferred.resolve(resultMap);
我认为以下应该有效:
let updateTags = (newTags, tagName, contentIds) => {
let deferred = Q.defer(),
resultMap = new Map(),
success_ids = [],
failed_ids = [],
counter = 1;
resultMap.set("success", success_ids);
resultMap.set("failed", failed_ids);
//promise will never be resolved if you have no content ids
if(contentIds.length === 0){
//not sure if Q.resolve exist but here you return a resolved
// promise with the empty success and failed arrays
$("#spinner").hide();
return Promise.resolve(resultMap);//resolve with empty value
}
contentIds.forEach(function (contentId) {
var tags = [];
osapi.jive.core.get({
v: "v3",
href: "/contents/" + contentId + ""
}).execute(function (content) {
tags = content.tags;
content["tags"] = _.union(tags, newTags);
osapi.jive.core.put({
v: "v3",
href: "/contents/" + contentId + "",
body: content
}).execute(function (response) {
counter++;
if (response.error) {
failed_ids.push(contentId);
} else {
success_ids.push(contentId);
}
if (counter === contentIds.length) {
deferred.resolve(resultMap);
$("#spinner").hide()
}
}, function (error) {
//I assume execute will either call one or the other function
// that is passed to it so increment counter here
counter++;
failed_ids.push(contentId);
if (counter === contentIds.length) {
deferred.resolve(resultMap);
$("#spinner").hide()
}
}
);
})
});
return deferred.promise;
};
推荐阅读
- java - 使用休眠从表中获取单个日期值
- ios - Why JSON data from decoder to become UITableView datasource does not assigns?
- django - 具有多个序列化程序的视图集上的 DRF 选项请求
- javascript - GeometryUtils.js:6 Uncaught ReferenceError: THREE is not defined at Object../node_modules/three/examples/js/utils/GeometryUtils.js
- amazon-web-services - 使用 rest api 在 Cloudtrail 中获取分离的卷日期
- angular - 如何在ionic4中使用路由器导航
- excel - Excel:仅引用文件名的一部分
- mysql - 在 MySQL 中,我们可以使用 COUNT 和 SUM 值来使用单个 SELECT 计算另一个输出列中的值吗?
- xamarin - Xamarin Forms - 从 2017 年到 2019 年更新 Visual Studio 后 iOS 上的奇怪行为
- go - Get Object 返回空字符串作为值 Golang