注意:我正在使用bluebird https://github.com/petkaantonov/bluebird/在这个答案中。
有 3 种方法可以实现您想要的功能:闭包、绑定和Promise.using
.
Closure这就是@Sukima 展示的方式。
function promisedFunc() {
var db;
return getCollection().then(function(col) {
db = col;
return db.query(stuff);
}).then(function() {
return db.query(otherStuff);
});
}
Binding: using Promise.bind
, 你(们)能做到this
将保存值的对象。
function promisedFunc() {
return getCollection().bind({}).then(function(col) {
this.db = col;
return this.db.query(stuff);
}).then(function() {
return this.db.query(otherStuff);
});
}
Finally最后一种方法是由 bluebird v2 引入的,是使用真正的资源管理。
function promisedFunc() {
return Promise.using(getDb(), function(db) {
return db.query(stuff).then(function() {
return db.query(otherStuff);
});
});
}
我将解释一下getDb
方法再往下。
最后一种方法提供了另一个非常有趣的好处:处置资源。例如,您经常需要调用close
数据库资源的方法。Promise.using
允许您创建处置器,一旦其中的承诺得到解决(或未解决)就运行。
要了解为什么这是一个优势,让我们回顾一下实现此目的的 3 种方法。
Closure:
var db, close;
return getCollection().spread(function(col, done) {
db = col;
close = done;
return db.query(stuff);
}).then(function() {
return db.query(otherStuff);
}).finally(function() {
close();
});
是的,这意味着每次使用数据库连接时都必须编写所有这些样板文件。没有其他选择。
现在我们看看绑定方式:
return getCollection().bind({}).spread(function(col, done) {
this.db = col;
this.close = done;
return this.db.query(stuff);
}).then(function() {
return this.db.query(otherStuff);
}).finally(function() {
this.close();
});
然而现在,这可以模块化。
var db = {
getDb: function() { return getCollection().bind({}); },
close: function() { this.close(); }
};
return db.getDb().then(function() {
return this.db.query(stuff);
}).then(function() {
return this.db.query(otherStuff);
}).finally(db.close);
这已经好很多了!但我们还是要考虑使用finally
.
然后按照bluebird介绍的方式,Promise.using
。通过这样声明:
function getDb() {
var close;
return getCollection().spread(function(db, done) {
close = done;
return db;
}).disposer(function() {
close();
});
}
您可以像以前一样简单地使用它:
return Promise.using(getDb(), function(db) {
return db.query(stuff).then(function() {
return db.query(otherStuff);
});
});
无需思考finally
,并且没有样板。