ExpressJS服务器中使用的javascript Map()的.has()、.get()和.set()的正确方法是什么?
javascript Map()让我感到厌烦。我的问题是关于javascript Map()-ExpressJS服务器中使用的javascript Map()的.has()、.get()和.set()的正确方法是什么?,javascript,node.js,express,Javascript,Node.js,Express,javascript Map()让我感到厌烦。我的问题是关于javascript Map()-set、get和has()。我以为我是这方面的专家,但显然不是 情境:我有一个“全局”地图-一个保存在不同的.js文件中的地图,该文件获取“必需”。此映射的键是MongoDB文档的\u id。此映射的值是npm包节点计划的类对象。值部分可以忽略,因为我的问题是.get()、.has()和.set() 以下是我取消作业(失败)的方法: 取消作业:异步函数(id){ log('----内部取消作业---')
set
、get
和has()
。我以为我是这方面的专家,但显然不是
情境:我有一个“全局”地图-一个保存在不同的.js
文件中的地图,该文件获取“必需”。此映射的键是MongoDB文档的\u id
。此映射的值是npm包节点计划的类对象。值部分可以忽略,因为我的问题是.get()、.has()和.set()
以下是我取消作业(失败)的方法:
取消作业:异步函数(id){
log('----内部取消作业---');
log('id=',id);
log('map=',config.map);
log('map size=',config.map.size);
if(config.map.has(id)){
log('----map具有id----');
让job=config.map.get(id);
log('job=',job);
等待作业。取消();
config.map.delete(id);
log('----从映射---'中删除了1);
}
},
if语句总是返回false。我以前尝试过.get()
,并检查返回值是否不是未定义的
,而是未定义的
。
在我执行了几次.set()
和(未能执行).delete()
之后,让我共享我的服务器的控制台日志-由上述代码生成:
id = 5f9c3b171a5d1b26089d60fe
map = Map {
5f9c3b171a5d1b26089d60fe => Job {
job: [Function],
callback: false,
name: '<Anonymous Job 1>',
trackInvocation: [Function],
stopTrackingInvocation: [Function],
triggeredJobs: [Function],
setTriggeredJobs: [Function],
cancel: [Function],
cancelNext: [Function],
reschedule: [Function],
nextInvocation: [Function],
pendingInvocations: [Function]
},
5f9c3b171a5d1b26089d60fe => Job {
job: [Function],
callback: false,
name: '<Anonymous Job 2>',
trackInvocation: [Function],
stopTrackingInvocation: [Function],
triggeredJobs: [Function],
setTriggeredJobs: [Function],
cancel: [Function],
cancelNext: [Function],
reschedule: [Function],
nextInvocation: [Function],
pendingInvocations: [Function]
}
}
map size = 2
我使用这个convertDocumentToScheduledJob
方法来设置/插入映射键值对。这整件事都是完整堆栈
web应用程序的一部分,因此有多个控制器调用这两种方法,但我非常确定这些方法不会直接影响这里的任何内容。他们只调用这两个方法
同样,如上面我的PS
消息所示,当我在控制台上记录config.map
时,它会显示两个具有相同键的映射条目~~这不令人担忧吗~~
编辑2:@FelixKling解决了这个问题。键是数据类型,
Object
。我必须将其转换为字符串
,才能解决这个问题。多谢各位
console.log('Type of job_id = ', typeof dbJob._id);
let strId = JSON.stringify(dbJob._id);
console.log('Type of strID = ', typeof strId);
config.map.set(strId, j);
@费利克斯克林在评论中解决了这个问题 键的数据类型为
Object
。我必须将其转换为字符串
,才能解决这个问题。多谢各位
console.log('Type of job_id = ', typeof dbJob._id);
let strId = JSON.stringify(dbJob._id);
console.log('Type of strID = ', typeof strId);
config.map.set(strId, j);
解决方案1(不完整):
- 这消除了重复密钥错误。新的地图条目现在可以用相同的键正确地替换旧的地图条目
- 当我调用
时,问题仍然存在,其中id是一个基本字符串值。stringified字符串与常规字符串不同。(它有一个额外的双引号)cancelJob(id)
- MongoDB文档展示了一种通过
方法将.toString()
转换为常规字符串的方法。[来源:;]\u id
解决方案2:
convertDocumentToScheduledJob:函数(dbJob){
// ...
设strId=dbJob.\u id.toString();
},
cancelJob:异步函数(原始id){
// ...
让id=typeof raw\u id=='object'?raw\u id.toString():raw\u id;
},
键在地图中是唯一的,这里缺少一些东西,您能否显示填充地图时的代码。当然可以。下面是设置映射的代码:
javascript convertDocumentToScheduledJob:function(dbJob){let j=scheduleJob(dbJob.recurrence=='no recurrence'?date:rule,function(){//does stuff})config.map.set(dbJob.\u id,j)
dbJob的类型是什么?@FelixKling捕捉得很好。结果是dbJob的类型。id是对象
。虽然它应该是一个字符串。这是一个重大突破。谢谢。编辑:dbJob是一个MongoDB文档。“…它显示了两个具有相同键的映射条目。这不令人担忧吗?”由于映射不可能有两个具有相同键的条目,因此唯一的结论是键必须不同,例如字符串对象就是这样。但是dbJob.\u id
可能是任何可能实现toString
的对象。
console.log('Type of job_id = ', typeof dbJob._id);
let strId = JSON.stringify(dbJob._id);
console.log('Type of strID = ', typeof strId);
config.map.set(strId, j);