什么是 Promise?
在说 Promise 之前,不得不说一下 JavaScript 的嵌套的回调函数
在 JavaScript 语言中,无论是写浏览器端的各种事件处理回调,ajax 回调,还是写 Node.js 上的业务逻辑,不得不面对的问题就是各种回调函数.回调函数少了还好,一旦多了起来而且必须讲究执行顺序的话,回调函数开始嵌套,那代码的恶心程度是相当不符合常人的线性思维的.
说到这里,我真有点想去了解一下响马老师的 fibjs,我没有接触过它,但它的编程方式就是线性的,更加符合常人思维.我个人认为 Promise 就是为了把 JS 复杂的嵌套转换成常人思维的线性代码.
// 就像下面这样:
// 你不在乎下面这三个ajax的执行顺序还好
// 如果你在乎顺序呢?
$.get('url', function(){
}, 'json');
$.get('url1', function(){
}, 'json');
$.get('url2', function(){
}, 'json');
// 就像这样?
$.get('url', function(){
$.get('url1', function(){
$.get('url2', function(){
}, 'json');
}, 'json');
}, 'json');
// 下面是我最近写的一段Node.js的代码
// 其实这个嵌套也不算多
// 如果业务逻辑相当复杂起来呢?
// 嵌套20 30层?
var adminIndex = function(params, callback){
storeAdmin.getApiTokens(function(err, tokens){
if ( err ) { callback(err); return; }
storeAdmin.getApiServices(function(err, apiServices){
if ( err ) { callback(err); return; }
storeAdmin.getSocketioServices(function(err, socketioServices){
if ( err ) { callback(err); return; }
callback(0, {
status : true,
data : {
api_tokens : tokens,
api_services : apiServices,
socketio_services : socketioServices
}
});
});
});
});
};
说了这么多,到底什么是 Promise 呢?
其实,Promise 就是一个类,而且这个类已经成为了 ES6 的标准,这个类目前在 chrome32,Opera19,Firefox29 以上的版本都已经支持了,要想在所有浏览器上都用上的话就看看 es6-promise 吧.
那 Promise 怎么用呢?
看一段很简单的代码,请注意阅读代码中的注释.
var val = 1;
// 我们假设step1, step2, step3都是ajax调用后端或者是
// 在Node.js上查询数据库的异步操作
// 每个步骤都有对应的失败和成功处理回调
// 需求是这样,step1,step2,step3必须按顺序执行
function step1(resolve, reject) {
console.log('步骤一:执行');
if (val >= 1) {
resolve('Hello I am No.1');
} else if (val === 0) {
reject(val);
}
}
function step2(resolve, reject) {
console.log('步骤二:执行');
if (val === 1) {
resolve('Hello I am No.2');
} else if (val === 0) {
reject(val);
}
}
function step3(resolve, reject) {
console.log('步骤三:执行');
if (val === 1) {
resolve('Hello I am No.3');
} else if (val === 0) {
reject(val);
}
}
new Promise(step1).then(function(val) {
console.info(val);
return new Promise(step2);
}).then(function(val) {
console.info(val);
return new Promise(step3);
}).then(function(val) {
console.info(val);
return val;
}).then(function(val) {
console.info(val);
return val;
});
// 执行之后将会打印
步骤一:执行Hello I am No.1步骤二:执行Hello I am No.2步骤三:执行Hello I am No.3 Hello I am No.3
Promise 到底解决什么问题?
正如上面代码所示,笔者认为,Promise 的意义就在于 then 链式调用 ,它避免了异步函数之间的层层嵌套,将原来异步函数的 嵌套关系 转变为便于阅读和理解的 链式步骤关系 .
Promise 的主要用法就是将各个异步操作封装成好多 Promise,而一个 Promise 只处理一个异步逻辑.最后将各个 Promise 用链式调用写法串联,在这样处理下,如果异步逻辑之间前后关系很重的话,你也不需要层层嵌套,只需要把每个异步逻辑封装成 Promise 链式调用就可以了.
Promise 常用的关键点
在 Promise 定义时,函数已经执行了
Promise 构造函数只接受一个参数,即带有异步逻辑的函数.这个函数在 new Promise 时已经执行了.只不过在没有调用 then 之前不会 resolve 或 reject.
在 then 中的 resolve 方法中如何 return?
在 then 方法中通常传递两个参数,一个 resolve 函数,一个 reject 函数.reject 暂时不讨论,就是出错的时候运行的函数罢了.resolve 函数必须返回一个值才能把链式调用进行下去,而且这个值返回什么是有很大讲究的.
resolve 返回一个新 Promise
返回一个新 Promise 之后再调用的 then 就是新 Promise 中的逻辑了.
resolve 返回一个值
返回一个值会传递到下一个 then 的 resolve 方法参数中.
来源: http://www.jianshu.com/p/e34729fc3a85