提取物的问题是,你的任务是异步的,但是你把它当作一个异步任务。你的任务完成并且你的过程存在,但你还没有创建你的表并执行你的insert
。
您需要做的是在registerTask
下面添加一行,创建一个done
函数。然后,当你的过程实际完成时,你可以调用这个done
函数。如果您曾经使用过mocha,那么您可能会熟悉这种模式。
/*jshint node:true */
'use strict';
var config = {
rethinkDB: {
host: 'localhost',
port: 28015,
dbName: 'test'
}
};
var r = require('rethinkdb');
module.exports = function (grunt) {
grunt.registerTask('default', 'Task to create rethinkDB tables', function() {
// 1. Declare your `done` function
var done = this.async();
return r.connect({
host: config.rethinkDB.host,
port: config.rethinkDB.port
}, function (err, conn) {
if (err) throw err;
return r.db(config.rethinkDB.dbName).tableCreate('tv_shows').run(conn, function (err, res) {
if (err) throw err;
console.log(res);
return r.table('tv_shows').insert({name: 'Star Trek TNG'}).run(conn, function (err, res) {
if (err) throw err;
console.log(res);
// 2. Call your `done` function once everything is done
done();
});
});
});
});
};
你的代码确实有一个其他的错误。我想你会多次运行它,基本上,你要确保这些表存在,但不希望它在表存在的时候抛出错误。 RethinkDB,默认情况下,如果你创建一个已经存在的表抛出一个错误,那么你应该考虑这样做:
return r.db(config.rethinkDB.dbName).tableCreate('tv_shows').run(conn, function (err, res) {
// Don't throw an error or consider doing handling the error
// if (err) throw err;
console.log(res);
// ...
承诺
你可能会考虑使用承诺使这个代码有点清洁:
module.exports = function (grunt) {
grunt.registerTask('default', 'Task to create rethinkDB tables', function() {
var done = this.async();
return r.connect({
host: config.rethinkDB.host,
port: config.rethinkDB.port
})
.then(function (conn) {
return r.db(config.rethinkDB.dbName).tableCreate('tv_shows').run(conn)
.catch(function() { })
.then(function() {
return r.table('tv_shows').insert({name: 'Star Trek TNG'}).run(conn);
});
})
.then(done);
});
};
非常感谢详细的回答,我熟悉摩卡,完全熟悉他们的异步性质,但不太熟悉grunt自定义任务,再次感谢 – Fouad