学习Promise

promise的立即执行性

let p = new Promise(function(resolve, reject) {
    console.log('create a promise') //这时立即执行的
    resolve('success')
}

console.log('after new promise')

p.then(function(value) {
    console.log(value)
})

执行结果:

'create a promise'
'after new promise'
'success'

promise三种状态

未完成态pending,完成态resolved,失败态rejected

var p1 = new Promise(function(resolve,reject){
  resolve(1); //同步代码,立即被调用了,状态为完成态
});
var p2 = new Promise(function(resolve,reject){
  setTimeout(function(){
    resolve(2);  // 异步代码,未被执行,状态为未完成态
  }, 500);      
});
var p3 = new Promise(function(resolve,reject){
  setTimeout(function(){
    reject(3);  // 异步代码,未被执行,状态为未完成态
  }, 500);      
});

console.log(p1);
console.log(p2);
console.log(p3);
setTimeout(function(){
  console.log(p2); // 2,延迟执行,此时p2和p3已被then()调用,状态改变
}, 1000);
setTimeout(function(){
  console.log(p3); // 3
}, 1000); 

p1.then(function(value){
  console.log(value);
}); // 1
p2.then(function(value){
  console.log(value);
}); // 2
p3.catch(function(err){
  console.log(err);
}); // 3

执行结果:

Promise { 1 } 
Promise { <pending> }
Promise { <pending> }
1
2
3
Promise { 2 }
Promise { <rejected> 3 }

状态的不可逆

let p =new Promise(function(resolve, reject) {
    resolve('success')
    resolve('success2')
    reject('reject')
})

p1.then(function(value) {
    console.log(value)
})

执行结果:

'success'

Promise的状态一旦变为resolved或者rejected时,状态就固定下来了,后续的调用resolve或者reject方法都不会改变已有的状态和值

链式调用

let p = new Promise(function(resolve, reject) {
    resolve(1)
})

p.then(function(value) {
    console.log(value) // 1
    return value * 2
}).then(function(value) {
    console.log(value) // 2
}).then(function(value) {
    console.log(value) // undefined
    return Promise.resolve('resolve') //返回resolved状态的promise
}).then(function(value) {
    console.log(value) // 'resolve'
    return Promise.reject('reject') // 返回rejected状态的promise
}).then(function(value) {
    console.log('resolve' + value) // 接收成功态的value
}, function(err) {
    console.log('reject' + err) //接收失败态的value reject reject
})

执行结果:

1
2
undefined
"resolve"
"reject: reject"

then方法啊返回一个新的Promise对象,函数的返回值作为then返回的Promise对象

Promise中的异常

var p1 = new Promise( function(resolve,reject){
  foo.bar();
  resolve( 1 );      
});

p1.then(
  function(value){
    console.log('p1 then value: ' + value);
  },
  function(err){
    console.log('p1 then err: ' + err); // 异常捕获
  }
).then(
  function(value){
    console.log('p1 then then value: '+value); // 之后被正确的函数调用
  },
  function(err){
    console.log('p1 then then err: ' + err);
  }
);

var p2 = new Promise(function(resolve,reject){
  resolve( 2 );    
});

p2.then(
  function(value){
    console.log('p2 then value: ' + value); // 执行
    foo.bar();
  }, 
  function(err){
    console.log('p2 then err: ' + err);
  }
).then(
  function(value){
    console.log('p2 then then value: ' + value);
  },
  function(err){
    console.log('p2 then then err: ' + err); // 异常捕获
    return 1; // 返回1
  }
).then(
  function(value){
    console.log('p2 then then then value: ' + value); // 之后被正确函数的调用
  },
  function(err){
    console.log('p2 then then then err: ' + err);
  }
)

执行结果:

p1 then err: ReferenceError: foo is not defined
p2 then value: 2
p1 then then value: undefined
p2 then then err: ReferenceError: foo is not defined
p2 then then then value: 1

异常一旦得到处理,then返回的后续Promise对象将恢复正常,并会被Promise执行成功的回调函数处理。另外,需要注意p1、p2 多级then的回调函数是交替执行的 ,这正是由Promise then回调的异步性决定的。

resolve

var p1 = Promise.resolve( 1 );
var p2 = Promise.resolve( p1 );
var p3 = new Promise(function(resolve, reject){
  resolve(1);
});
var p4 = new Promise(function(resolve, reject){
  resolve(p1);
});

console.log(p1 === p2); 
console.log(p1 === p3);
console.log(p1 === p4);
console.log(p3 === p4);

p4.then(function(value){
  console.log('p4=' + value);
});

p2.then(function(value){
  console.log('p2=' + value);
})

p1.then(function(value){
  console.log('p1=' + value);
})

控制台输出:

true
false
false
false
p2=1
p1=1
p4=1

Promise.resolve(…)可以接收一个值或者是一个Promise对象作为参数。当参数是普通值时,它返回一个resolved状态的Promise对象,对象的值就是这个参数;当参数是一个Promise对象时,它直接返回这个Promise参数。因此,p1 === p2。但通过new的方式创建的Promise对象都是一个新的对象,因此后面的三个比较结果都是false。另外,为什么p4的then最先调用,但在控制台上是最后输出结果的呢?因为p4的resolve中接收的参数是一个Promise对象p1,resolve会对p1”拆箱“,获取p1的状态和值,但这个过程是异步的

拆箱的概念应该是micro task和macro task吧???

    原文作者:luckyzv
    原文地址: https://segmentfault.com/a/1190000010491966
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞