Промисификация
Промисификация означает преобразование существующего API, не использующего промисы, в API, возвращающий промисы.
Обычный способ использования промисов в Node.js — Promise.promisifyAll некоторый API и начало вызова исключительно версий методов API, возвращающих промисы. Например:
var fs = require("fs");
Promise.promisifyAll(fs);
// Now you can use fs as if it was designed to use bluebird promises from the beginning
fs.readFileAsync("file.js", "utf8").then(...)
Обратите внимание, что вышеприведённый случай является исключительным, так как fs — это единственный экземпляр. Большинство библиотек можно промисифицировать, потребовав классы библиотеки (конструкторские функции) и вызвав promisifyAll на .prototype. Это необходимо сделать только один раз за всё время жизни приложения, и после этого можно использовать методы библиотеки точно так, как они описаны, за исключением добавления "Async"-суффикса к вызовам методов и использования интерфейса промисов вместо интерфейса обратных вызовов.
В качестве примечательного исключения в fs, fs.existsAsync не работает как ожидается, потому что Node.js fs.exists не вызывает обратный вызов с ошибкой в качестве первого аргумента. Подробнее см. #418. Одним из возможных решений является использование fs.statAsync.
Вот несколько примеров применения вышеуказанной практики к некоторым популярным библиотекам:
// The most popular redis module
var Promise = require("bluebird");
Promise.promisifyAll(require("redis"));
// The most popular mongodb module
var Promise = require("bluebird");
Promise.promisifyAll(require("mongodb"));
// The most popular mysql module
var Promise = require("bluebird");
// Note that the library's classes are not properties of the main export
// so we require and promisifyAll them manually
Promise.promisifyAll(require("mysql/lib/Connection").prototype);
Promise.promisifyAll(require("mysql/lib/Pool").prototype);
// Mongoose
var Promise = require("bluebird");
Promise.promisifyAll(require("mongoose"));
// Request
var Promise = require("bluebird");
Promise.promisifyAll(require("request"));
// Use request.getAsync(...) not request(..), it will not return a promise
// mkdir
var Promise = require("bluebird");
Promise.promisifyAll(require("mkdirp"));
// Use mkdirp.mkdirpAsync not mkdirp(..), it will not return a promise
// winston
var Promise = require("bluebird");
Promise.promisifyAll(require("winston"));
// rimraf
var Promise = require("bluebird");
// The module isn't promisified but the function returned is
var rimrafAsync = Promise.promisify(require("rimraf"));
// xml2js
var Promise = require("bluebird");
Promise.promisifyAll(require("xml2js"));
// jsdom
var Promise = require("bluebird");
Promise.promisifyAll(require("jsdom"));
// fs-extra
var Promise = require("bluebird");
Promise.promisifyAll(require("fs-extra"));
// prompt
var Promise = require("bluebird");
Promise.promisifyAll(require("prompt"));
// Nodemailer
var Promise = require("bluebird");
Promise.promisifyAll(require("nodemailer"));
// ncp
var Promise = require("bluebird");
Promise.promisifyAll(require("ncp"));
// pg
var Promise = require("bluebird");
Promise.promisifyAll(require("pg"));
Во всех вышеперечисленных случаях библиотека каким-то образом предоставила свои классы. Если это не так, вы всё равно можете промисифицировать, создав одноразовый экземпляр:
var ParanoidLib = require("...");
var throwAwayInstance = ParanoidLib.createInstance();
Promise.promisifyAll(Object.getPrototypeOf(throwAwayInstance));
// Like before, from this point on, all new instances + even the throwAwayInstance suddenly support promises
См. также Promise.promisifyAll.
© 2013–2018 Petka Antonov
Licensed under the MIT License.
http://bluebirdjs.com/docs/api/promisification.html