Promise.using
Promise.using(
Promise|Disposer|any resource,
Promise|Disposer|any resource...,
function(any resources...) handler
) -> Promise
Promise.using(
Array<Promise|Disposer|Any> resources,
function(Array<any> resources) handler
) -> Promise
In conjunction with
, .disposer
using
will make sure that no matter what, the specified disposer will be called when the promise returned by the callback passed to using
has settled. The disposer is necessary because there is no standard interface in node for disposing resources.
Here is a simple example (where getConnection()
has been defined to return a proper Disposer object)
using(getConnection(), function(connection) {
// Don't leak the `connection` variable anywhere from here
// it is only guaranteed to be open while the promise returned from
// this callback is still pending
return connection.queryAsync("SELECT * FROM TABLE");
// Code that is chained from the promise created in the line above
// still has access to `connection`
}).then(function(rows) {
// The connection has been closed by now
console.log(rows);
});
Using multiple resources:
using(getConnection(), function(conn1) {
return using(getConnection(), function(conn2) {
// use conn1 and conn 2 here
});
}).then(function() {
// Both connections closed by now
})
The above can also be written as (with a caveat, see below)
using(getConnection(), getConnection(), function(conn1, conn2) {
// use conn1 and conn2
}).then(function() {
// Both connections closed by now
})
However, if the second getConnection
throws synchronously, the first connection is leaked. This will not happen
when using APIs through bluebird promisified methods though. You can wrap functions that could throw in
which will turn synchronous rejections into rejected promises.Promise.method
Note that you can mix promises and disposers, so that you can acquire all the things you need in parallel instead of sequentially
// The files don't need resource management but you should
// still start the process of reading them even before you have the connection
// instead of waiting for the connection
// The connection is always closed, no matter what fails at what point
using(readFile("1.txt"), readFile("2.txt"), getConnection(), function(txt1, txt2, conn) {
// use conn and have access to txt1 and txt2
});
You can also pass the resources in an array in the first argument. In this case the handler function will only be called with one argument that is the array containing the resolved resources in respective positions in the array. Example:
var connectionPromises = [getConnection(), getConnection()];
using(connectionPromises, function(connections) {
var conn1 = connections[0];
var conn2 = connections[1];
// use conn1 and conn2
}).then(function() {
// Both connections closed by now
})