promise出现的动机
在javascript的世界中,所有代码都是单线程执行的。
由于这个缺陷,导致所有的的网络操作,浏览器事件都是由异步执行。异步执行可以用回调实现,ajax就是典型的异步操作
如下代码在纯JavaScript中实现它们并使用它们来包装现有的异步操作:
function readJSON(filename, callback){
fs.readFile(filename, 'utf8', function (err, res){
if (err) return callback(err);
try {
res = JSON.parse(res);
} catch (ex) {
return callback(ex);
}
callback(null, res);
});
}
复制代码
以上代码缺点
有很多,实现多次回调会使我们的代码变得非常混乱。
promise描述
promise(承诺)
承诺背后的核心思想是承诺代表异步操作的结果。
一个 Promise有以下几种状态:
- pending: 初始状态,既不是成功,也不是失败状态。
- fulfilled: 意味着操作成功完成。
- rejected: 意味着操作失败。
pending 状态的 Promise 对象可能触发fulfilled 状态并传递一个值给相应的状态处理方法,也可能触发失败状态(rejected)并传递失败信息。当其中任一种情况出现时,Promise 对象的 then 方法绑定的处理方法(handlers )就会被调用(then方法包含两个参数:onfulfilled 和 onrejected,它们都是 Function 类型。当Promise状态为fulfilled时,调用 then 的 onfulfilled 方法,当Promise状态为rejected时,调用 then 的 onrejected 方法, 所以在异步操作的完成和绑定处理方法之间不存在竞争。
new Promise((resolve,reject)=>{
}).then((data)=>{
},err=>{
}).catch(()=>{
})
复制代码
promise私有方法
Promise.all(iterable)
这个方法返回一个新的promise对象,该promise对象在iterable参数对象里所有的promise对象都成功的时候才会触发成功,一旦有任何一个iterable里面的promise对象失败则立即触发该promise对象的失败。这个新的promise对象在触发成功状态以后,会把一个包含iterable里所有promise返回值的数组作为成功回调的返回值,顺序跟iterable的顺序保持一致;如果这个新的promise对象触发了失败状态,它会把iterable里第一个触发失败的promise对象的错误信息作为它的失败错误信息。Promise.all方法常被用于处理多个promise对象的状态集合。
Promise.race(iterable)
当iterable参数里的任意一个子promise被成功或失败后,父promise马上也会用子promise的成功返回值或失败详情作为参数调用父promise绑定的相应句柄,并返回该promise对象
Promise.reject(reason)
返回一个状态为失败的Promise对象,并将给定的失败信息传递给对应的处理方法
Promise.resolve(value)
返回一个状态由给定value决定的Promise对象。
promise原型方法
Promise.prototype.catch(onRejected)
添加一个拒绝(rejection) 回调到当前 promise, 返回一个新的promise。当这个回调函数被调用,新 promise 将以它的返回值来resolve,否则如果当前promise 进入fulfilled状态,则以当前promise的完成结果作为新promise的完成结果.
Promise.prototype.then(onFulfilled, onRejected)
添加解决(fulfillment)和拒绝(rejection)回调到当前 promise, 返回一个新的 promise, 将以回调的返回值来resolve。
Promise.prototype.finally(onFinally)
添加一个事件处理回调于当前promise对象,并且在原promise对象解析完毕后,返回一个新的promise对象。回调会在当前promise运行完毕后被调用,无论当前promise的状态是完成(fulfilled)还是失败(rejected)
jQuery中的promise规范
jquery用deferred实现了Promise规范,$.Deferred是个什么玩意呢?还是老方法,打印出来看看,先有个直观印象:
var def = $.Deferred();
console.log(def);
复制代码
$.Deferred()返回一个对象,我们可以称之为Deferred对象,上面挂着一些熟悉的方法如:
done、fail、then
等。jquery就是用这个Deferred对象来注册异步操作的回调函数,修改并传递异步操作的状态。
Node.js的promise
安装promise:
npm install promise --save
复制代码
然后你可以使用它将它加载到一个局部变量中 require
var Promise = require('promise');
复制代码
"promise"库还提供了一些与node.js交互的真正有用的扩展
var readFile = Promise.denodeify(require('fs').readFile);
function readJSON(filename, callback){
return readFile(filename, 'utf8')
.then(JSON.parse)
.nodeify(callback);
}
复制代码