首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Mongoose pre.save()异步中间件无法创建记录

Mongoose pre.save()异步中间件无法创建记录
EN

Stack Overflow用户
提问于 2014-12-03 12:44:06
回答 2查看 982关注 0票数 0

我使用keystone@0.2.32。我想将帖子类别更改为树形结构。下面的代码运行良好,除了当我创建一个类别时,它进入了死锁:

代码语言:javascript
运行
复制
var keystone = require('keystone'),
	Types = keystone.Field.Types;

/**
 * PostCategory Model
 * ==================
 */

var PostCategory = new keystone.List('PostCategory', {
	autokey: { from: 'name', path: 'key', unique: true }
});

PostCategory.add({
	name: { type: String, required: true },
	parent: { type: Types.Relationship, ref: 'PostCategory' },
	parentTree: { type: Types.Relationship, ref: 'PostCategory', many: true }
});

PostCategory.relationship({ ref: 'Post', path: 'categories' });

PostCategory.scanTree = function(item, obj, done) {
	if(item.parent){
		PostCategory.model.find().where('_id', item.parent).exec(function(err, cats) {
			if(cats.length){
				obj.parentTree.push(cats[0]);
				PostCategory.scanTree(cats[0], obj, done);
			}
		});
	}else{
		done();
	}
}

PostCategory.schema.pre('save', true, function (next, done) { //Parallel middleware, waiting done to be call
	if (this.isModified('parent')) {
        this.parentTree = [];
		if(this.parent != null){
			this.parentTree.push(this.parent);
			PostCategory.scanTree(this, this, done);
		}else
			process.nextTick(done);
    }else
		process.nextTick(done); //here is deadlock.

    next();
});

PostCategory.defaultColumns = 'name, parentTree';
PostCategory.register();

非常感谢。

EN

回答 2

Stack Overflow用户

发布于 2014-12-06 19:08:52

正如我在您登录Keystone的问题上所解释的那样:https://github.com/keystonejs/keystone/issues/759

这似乎是mongoose中的一个可重现的错误,它会阻止中间件在以下情况下进行解析:

先运行

  • 并行中间件执行查询,然后运行
  • 串行中间件执行查询

更改Keystone的autokey中间件以并行模式运行可能会在其他用例中导致错误,因此无法实现。答案是以串行模式而不是并行模式实现您的parentTree中间件。

另外,我还注意到了其他一些事情:

  • 您的中间件中有一个错误,其中第一个父级被添加到数组中两次。
  • scanTree方法最好作为schama
  • 上的方法实现您可以将findById方法用于更简单的父级查询

<代码>F217

schema方法如下所示:

代码语言:javascript
运行
复制
PostCategory.schema.methods.addParents = function(target, done) {
    if (this.parent) {
        PostCategory.model.findById(this.parent, function(err, parent) {
            if (parent) {
                target.parentTree.push(parent.id);
                parent.addParents(target, done);
            }
        });
    } else {
        done();
    }
}

修复后的中间件如下所示:

代码语言:javascript
运行
复制
PostCategory.schema.pre('save', function(done) {
    if (this.isModified('parent')) {
        this.parentTree = [];
        if (this.parent != null) {
            PostCategory.scanTree(this, this, done);
        } else {
            process.nextTick(done);
        }
    } else {
        process.nextTick(done);
    }
});
票数 1
EN

Stack Overflow用户

发布于 2014-12-04 07:13:00

我认为这是keystone.js的一个bug。我更改了schemaPlugins.js 104行

从…

代码语言:javascript
运行
复制
this.schema.pre('save', function(next) {

代码语言:javascript
运行
复制
this.schema.pre('save', true, function(next, done) {

并从第124行更改为以下内容,

代码语言:javascript
运行
复制
		// if has a value and is unmodified or fixed, don't update it
		if ((!modified || autokey.fixed) && this.get(autokey.path)) {
			process.nextTick(done);
			return next();
		}

		var newKey = utils.slug(values.join(' ')) || this.id;

		if (autokey.unique) {
			r = getUniqueKey(this, newKey, done);
			next();
			return r;
		} else {
			this.set(autokey.path, newKey);
			process.nextTick(done);
			return next();
		}

它起作用了。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27263791

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档