这个东西经常出现, 出现 then 的地方, 就会有 promise. 经常会看到,
a.then().then().catch();
我先粗略的说一下是什么意思, a 里会先进行一些操作, 然后做 then 里的内容, 然后再做接下来 then 里的内容, 然后再做接下来 then 里的内容, 最后 catch() 里再收集错误的 then(包括 a), 然后进行集中处理, 还是挺美滋滋的.
为什么这么写, 或者说为什么需要 Promise?
少年你听说过回调吗? 听过我就不用回答这个问题了, 如果你没有听说过, 那么我就这么说吧:
语言都有需要异步编程的时候, java 有各种锁, go 有 go 协程. 那我大 JS 经过发展, 有 promise 和 await&async. 他们都可以完成: 等需要的条件满足后, 我再做什么什么事儿.
a.then().then().then()
就是这样, a 的内容做完, 我才能做 then,then 的内容做完, 才能做下一个 then, 从左到右, 依次完成.
创建
var a= new Promise(
function(resolve, reject){
...
}
);
这样 a 就可以写一个 then() 了, then 怎么写下面马上说.
从上面的代码可以看出, 其实这个 promise 就是一个类的使用吗~
传一个函数, 做为 promise 的参数. 那我现在就讲讲这个传进来的参数.
function(resolve,reject){}
要注意的是: resolve 与 reject 根本就不是变量, 他们是两个系统自带的函数, resolve 是指, 如果操作完成, 调用 resolve() 通知执行 then(), 那就来写一个 then().
var a= new Promise(
//es6 箭头函数
(reslove,reject)=>{
let i=6;
if(i%2==0){
console.log("成功了");
reslove();
}else{
console.log("失败了呢~");
reject();}
}
);
c.then(
value=>console.log(value),
error=>console.log(error)
)
肯定会有疑问: then() 里应该怎么写?
借着上面的例子, 可以很清楚的看到, then 里就是两个函数, 也可以写一个函数. 第一个是上一步成功之后的函数, 第二个是上一步失败之后的函数. 如果只是写一个, 那么就表示上一步成功之后才执行这个, 失败了, 就结束了.
也许还会有疑问, 这个 value 和 error 是个什么东西?
value 是成功之后, 我们自定义的值, 用来传一些我们需要的东西, 同理, error 是失败之后, 我们自定义的值, 用来传一些我们需要的东西.
还么问题来了? 怎么传?
你是想在 then 中用之前 a 传过来的值吧? 那就回到之前 a 中.
reslove(带上你的数据); reject(带上你的数据);
找找上一段函数他们的位置吧.
var a=new Promise(
(reslove,reject)=>{
let i=6;
if(i%2==0){
console.log("成功了");
reslove( "成功了呢");
}else{
console.log("失败了呢~");
reject("失败了呢");
}
}
);
a.then(
value=>console.log(value),
error=>console.log(error)
)
我知道的, 还会有疑问的, 怎么搞 then().then()?
在第二个 then 中再返回一个 promise 就完事了.
var a=new Promise(
(reslove,reject)=>{
let i=6;
if(i%2==0){
console.log("成功了");
reslove( "成功了呢");
}else{
console.log("失败了呢~");
reject("失败了呢");}
}
);
var b=new Promise(
(reslove,reject)=>{
let i=6;
if(i%2==0){
console.log("b 成功了");
reslove( "b 成功了呢");
}else{
console.log("b 失败了呢~");
reject("b 失败了呢");}
}
);
a.then(
value=>b,
// 你也可以在这里 new Promise(xx){xx}
error=>console.log(error)
).then(value=>console.log("做完了做完了"))
讲讲 promise 中异常的处理
promise 中的任何错误都会调用 reject! 而且外部不能捕捉. 比如:
try {
a.then().then()
} catch(e) {}
这种 try/catch 的方式是抓不到异常的. 还有, then() 本身就会返回一个新的 promise, 手动返回则令说, 上代码说明一下, 这段代码也是没错的. 看最后几句就可以了.
var a=new Promise(
(reslove,reject)=>{
let i=6;
if(i%2==0){
console.log("成功了");
reslove( "成功了呢");
}
else{
console.log("失败了呢~");
reject("失败了呢");}
}
);
var b=new Promise(
(reslove,reject)=>{
let i=6;
if(i%2==0){
console.log("b 成功了");
reslove( "b 成功了呢");}
else{
console.log("b 失败了呢~");
reject("b 失败了呢");}
}
);
a.then(
value=>b,
error=>console.log(error)
).then(value=>console.log("做完了做完了")).then(()=>console.log("问题不大~~~"))
所以就算是 then() 的上一环没返回 promise 也没什么关系. 它仍然不会把异常丢给外部.
那 catch() 呢? 为什么要
a.then().then().catch()
这样写
我逗你玩的, 没有 catch 这个函数 catch() 用来捉上面 a.then().then() 这三段里错误, 任意一段出错, 都将直接跳到结尾的 catch 中, 其实 error 的值就是当前的 promise 返回的. 这里就会有一个新的问题, 那 then 的第二个处理错误的函数不就不用写了? 直接把所有的错误扔到 catch 里不是更爽么? 对! 就是这么写更好!
事实上, 在 then 中写第二个函数, 有一个缺点:
then 中的第二个函数, 只能处理前一个函数的错误, 如果是当前是最后一个 then, 当前的有错误就会很尴尬的处理不了, 因为 promise 中的任何错误都会调用 reject! 你也许会有疑问, then 的上一个 then 只返回了一个普通函数, 那普通函数发错误就不在 promise 里了.
那万一 catch() 中又有错误了呢?
catch().catch()
别的
Promise.race( [p1, p2, p3] )
p1,p2,p3 只要有一个做好, 就下一个 then
Promise.all([p1, p2, p3] )
p1,p2,p3 全做好, 才下一个 then
然后呢, 大家就都用 await/async 了, promise 用的少了.... 还得去搞下后面的两兄弟.
来源: http://www.jianshu.com/p/0352c0b59a2e