提取物的問題是,你的任務是異步的,但是你把它當作一個異步任務。你的任務完成並且你的過程存在,但你還沒有創建你的表並執行你的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