Promise
摘要
promise 主要是为了解决异步回调,现在node的实现就是基于promise, promise 的好处在于存在链式调用关系,同时解放了多层级回调管理。
常见用法
// 定义一个异步promise
var p = new Promise(function(resolve, reject){
// 异步请求
fetch('xxxx', function(data){
// 返回数据
resolve(data);
})
})
// promise 执行完后的回调
p.then(function(data){
//todo sth
}).catch(function(e){
//处理异常
})
常见API
1. Promise.all 所有promise 同步执行,全部返回结果才进入then, !!注意与 reduce 的区别
Promise.all([p1, p2, p3]).then(function(data){
// data[0] 是p1 返回的数据, data[1] 是 p2 返回的数据 , 依此类推
})
2. Promise.race 只要有一个promise 返回就执行 , 应用场景:比如探寻多个Url 是否有效,只要有一个url有效就可以了
Promise.race([p1, p2, p3]).then(function(data){
})
进阶
1. props 处理一个 promise 的 map 集合。只有有一个失败,所有的执行都结束
Promise.props({
a: getName(),
b: getContent(),
c: getComment()
}).then(function(result) {
console.log(result);
});
2. some 同时运行,结果是按照完成时间排序,感觉使用率不是很高,适用于寻找多种可能性的场景
http://bluebirdjs.com/docs/api/promise.some.html
Promise.some([
ping("ns1.example.com"),
ping("ns2.example.com"),
ping("ns3.example.com"),
ping("ns4.example.com")
], 2).spread(function(first, second) { // 记录最快的两个日志
console.log(first, second);
});
If too many promises are rejected so that the promise can never become fulfilled, it will be immediately rejected with an AggregateError of the rejection reasons in the order they were thrown in.
这个看的不是很明白
3. map 所有请求完成才算完成,任何reject 整体 reject
Promise.map(fileNames, function(fileName) {
return fs.readFileAsync(fileName)
.then(JSON.parse)
.catch(SyntaxError, function(e) {
e.fileName = fileName;
throw e;
})
}, {concurrency: concurrency}).then(function(parsedJSONs) {
console.log(parsedJSONs);
}).catch(SyntaxError, function(e) {
console.log("Invalid JSON in file " + e.fileName + ": " + e.message);
});
4. reduce 依次顺序执行,一旦有任何一个reject,全部reject
Promise.reduce(["file1.txt", "file2.txt", "file3.txt"], function(total, fileName) {
return fs.readFileAsync(fileName, "utf8").then(function(contents) {
return total + parseInt(contents, 10);
});
}, 0).then(function(total) {
//Total is 30
});
说说jquery的promise
使用 $.Deffered 对象实现异步
var wait = function(){
var dtd = $.Deferred(); // 生成Deferred对象
setTimeout(function(){
alert("执行完毕!");
dtd.resolve(); // 改变Deferred对象的执行状态
},5000);
return dtd;
};
$.when(wait()).done(function(){ alert("哈哈,成功了!"); })
.fail(function(err){ alert("出错啦!"); });
后续
1. TC39 stage0 有可以取消promise操作的API ,相信会很快崛起
提案地址: http://link.zhihu.com/?target=https%3A//github.com/tc39/proposals/blob/master/stage-0-proposals.md
计划、执行、每天高效的活着学着