Promise对象已在ECMAScript 2015中被写入标准,且已被最新版本的浏览器和Node.js/IO.js所支持。bluebird是一个第三方Promise规范实现库,它不仅完全兼容原生Promise对象,且比原生对象功能更强大。相比其它第三方类库或标准对象来说,bluebird拥有以下优点:功能更齐全而不臃肿、浏览器兼容性更好。
安装
npm install bluebird
使用
var Promise = require('bluebird');
这里只做一下简单介绍,更多还请移步至官网。
Promise包装器(Promisification)官方文档叫做Promisification,意思是将一个没有Promise的API对象包装成有Promise的API对象,即将其Promise化,或者可以理解成Promise包装器。
bluebird中有用于单个函数包装的Promise.promisify方法,也有用于对象属性包装的Promise.promisifyAll方法。
Promise.promisify - 单个函数对象的Promise化
var Promise = require("bluebird");
Promise.promisify(
function(any arguments..., function callback) nodeFunction,
[Object {
multiArgs: boolean=false,
context: any=this
} options]
) -> function
将Node.js对象nodeFunction包装为Promise对象,包装后将使用.then、.catch等Promise方法代替Node.js中的回调。如我们可以像下面这样将Node.js中fs模块中的readFile方法包装成一个Promise对象:
var Promise = require("bluebird");
var readFile = Promise.promisify(require("fs").readFile);
readFile("myfile.js", "utf8").then(function(contents) {
return eval(contents);
}).then(function(result) {
console.log("The result of evaluating myfile.js", result);
}).catch(SyntaxError, function(e) {
console.log("File had syntax error", e);
//捕获错误
}).catch(function(e) {
console.log("Error reading file", e);
});
Promise.promisifyAll - 对象属性的Promise化
Promise.promisifyAll(
Object target,
[Object {
suffix: String="Async",
multiArgs: boolean=false,
filter: boolean function(String name, function func, Object target, boolean passesDefaultFilter),
promisifier: function(function originalFunction, function defaultPromisifier)
} options]
) -> Object
将传入的对象实体的属性包装成Promise对象。如我们可以fs模块中的所有方法都Promise化:
var Promise = require("bluebird");
var fs = Promise.promisifyAll(require("fs"));
fs.readFileAsync("myfile.js", "utf8").then(function(contents) {
console.log(contents);
}).catch(function(e) {
console.error(e.stack);
});
Promise.asCallback - Promise对象的callback化
.asCallback(
[function(any error, any value) callback],
[Object {spread: boolean=false} options]
) -> this
.nodeify(
[function(any error, any value) callback],
[Object {spread: boolean=false} options]
) -> this
为Promise实例注册Node.js式的callback回调。如对于如下一个Promise实例注册为Node.js的回调:
function getDataFor(input, callback) {
return dataFromDataBase(input).asCallback(callback);
}
我们会像这样使用这个Promise实例:
getDataFor("me").then(function(dataForMe) {
console.log(dataForMe);
});
但将其回调化后,就可以像下面这样使用:
getDataFor("me", function(err, dataForMe) {
if( err ) {
console.error( err );
}
console.log(dataForMe);
});
Promise.delay - 延时执行
Promise.delay(
int ms,
[any|Promise<any> value=undefined]
) -> Promise
将指定的Promise对象value延时ms毫秒后执行
var Promise = require("bluebird");
Promise.delay(500).then(function() {
console.log("500 ms passed");
return "Hello world";
}).delay(500).then(function(helloWorldString) {
console.log(helloWorldString);
console.log("another 500 ms passed") ;
});
.delay - 实例延时执行
.delay(int ms) -> Promise
相当于Promise.delay(ms, this)。
.timeout - 实例超时
.timeout(
int ms,
[String message="operation timed out"]
) -> Promise
.timeout(
int ms,
[Error error]
) -> Promise
返回一个在指定时间ms后变为失败状态的promise。
var Promise = require("bluebird");
var fs = Promise.promisifyAll(require('fs'));
fs.readFileAsync("huge-file.txt").timeout(100).then(function(fileContents) {
// 执行成功的一些操作
}).catch(Promise.TimeoutError, function(e) {
console.log("could not read file within 100ms");
});