【发布时间】:2014-02-25 17:02:37
【问题描述】:
我正在为我的 Node.js 应用程序启动一个集成测试套件。我目前正在尝试编写一个设置脚本来擦除测试数据库并用一些测试数据填充它。我试图避免可怕的"Pyramid of Doom",我希望使用 Promise 来防止我的代码失控。我对 Promise 很陌生,但我仍在努力思考它们 - 可能我没有正确使用它们。
这是我没有承诺的初始版本。这可行,但在 wazoo 上嵌套了回调:
var mongoose = require('mongoose');
var User = require('./user');
var MONGODB_URL = process.env.MONGODB_TEST_URL || 'localhost:27017/swot_test';
console.log('\nRunning e2e test preparation script');
console.log('-----------------------------------\n');
console.log('Connecting to database:', MONGODB_URL, '...')
mongoose.connect(MONGODB_URL, function () {
console.log('Wiping database...')
mongoose.connection.db.dropDatabase(function () {
console.log('Setting up test user...')
User.createUser({
email: 'test@example.com',
password: 'tester'
}, function (err, user) {
if (err) throw err;
// If there was more setup, it would have to go here... pyramid of doom!
console.log('Finished.');
process.exit();
});
});
});
这是一个使用Q promises的版本:
var Q = require('q');
var mongoose = require('mongoose');
var User = require('./user');
var MONGODB_URL = process.env.MONGODB_TEST_URL || 'localhost:27017/swot_test';
console.log('\nRunning e2e test preparation script');
console.log('-----------------------------------\n');
Q.fcall(function () {
var deferred = Q.defer();
console.log('Connecting to database:', MONGODB_URL, '...');
mongoose.connect(MONGODB_URL, function (err) {
if (err) deferred.reject(new Error(err));
else deferred.resolve();
});
return deferred.promise;
})
.then(function () {
var deferred = Q.defer();
console.log('Wiping database...');
mongoose.connection.db.dropDatabase(function (err) {
if (err) deferred.reject(new Error(err));
else deferred.resolve();
});
return deferred.promise;
})
.then(function () {
var deferred = Q.defer();
console.log('Setting up test user...');
User.createUser({
email: 'test@example.com',
password: 'tester'
}, function (err, user) {
if (err) deferred.reject(new Error(err));
else deferred.resolve();
});
return deferred.promise;
})
.done(function () {
console.log('Finished.');
process.exit();
}, function (err) {
console.error('An error occurred:', err.stack);
});
我喜欢它有更少的嵌套,但里面有很多重复。有没有办法可以使用Q API 中的辅助函数来使这段代码更简洁、更少重复?尤其是这部分:
if (err) deferred.reject(new Error(err));
else deferred.resolve();
对于清理此代码的任何帮助,我将不胜感激。
【问题讨论】:
标签: javascript node.js mongoose promise q