ES6+Nodejs+Mongoose建立缓存一些常用数据的单例class,只有在setTimeout()中调用才正常?

新手上路,请多包涵

问题:

在 Nodejs 中使用 ES6 的写法用 class 来写一个能实现数据库采用数据缓存的类, 结果搞不定.
只有在 setTimeout() 中能在控制台打印出来我想要的结果.
我是全自学, 如果哪里理解错了, 请解惑. 谢谢了.

代码:

// mongoose 生成的 model 集合, 包含 "Category", "Unit" 这两个 model
const Models = require('../../db')
    .Models

// 单例类
class Cache {
    static get instance() {
        if (!this.model) this.model = new Model_con()
        return this.model
    }
}
Cache.model = undefined

// 缓存初始化类
class Model_con {
    constructor() {
        Model_con.makeProps(this)
            .then(() => this)
    }

    static makeProps(model) {
        model.isNew = true
        model.createTime = Date.now()
        model._cache = {}
        let pArr = []
        for (let m of['Category', 'Unit']) {
            pArr.push(Models[m].find()
                .then(res => {
                    return {
                        key: m,
                        value: res
                    }
                })
            )
        }

        return Promise.all(pArr)
            .then(this.initModel)
            .then(res => {
                return this.callback(res, model)
            })

    }

    static initModel(dataArr) {
        let output = {}
        for (let res of dataArr) {
            let arr = []
            for (let v of res.value) {
                let id = v._id
                delete v._doc._id
                let value = v._doc
                arr.push([id, value])
            }
            output[res.key] = arr
        }
        return output
    }

    static callback(dataArr, model) {
        let keys = Object.keys(dataArr)
        for (let key of keys) {
            model._cache[key] = new Map(dataArr[key])
        }
    }

}

let vs = Cache.instance
setTimeout(function() {
    console.log(vs)        //只有这样才能正常获取到单例的 Model_con 实例, 打印结果在下一块儿代码
}, 2000)
console.log(vs)            //只能取到 Model_con { isNew: true, createTime: 1488927391631, _cache: {} }

正常期望的打印结果:

Model_con {
  isNew: true,
  createTime: 1488927391631,
  _cache: 
   { Category: 
      Map {
        'H1GkV-Mx5x' => [Object],
        'SJk4Wzg5l' => [Object],
        'S1ZyNZGe9l' => [Object],
        // ...省略
        }
    },
    { Unit:
       Map: {
       'BJoFagGg9g' => [Object],
       'r13YTeGl9g' => [Object],
       'B1pY6eMx5x' => [Object],
       // ...省略
       }
    }
}
阅读 3.2k
1 个回答

你大概是没有理解node.js的event loop和promise的语义吧
Model_con.makeProps(this)里面有异步操作(Model.find),在你最后一行打印vs的时候异步操作还没有完成,所以cache是空的,setTimeout 2秒以后异步操作完成了,cache里面才有值
你可以看一下这篇关于event loop的文章

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题