promise详解

1.创建Promise的时候是立即执行的(同步)

let p = new Promise(function(resolve, reject){
  console.log("new promise"); //同步执行
  resolve("success");
});
console.log("after new Promise");
p.then(function(value){ //异步
  console.log(value);
});
输出
"new promise"
"after new Promise"
"success"

但在创建Promise对象时,作为Promise函数内部代码是会被立即执行的,只是执行的代码可以是异步代码

2.Promise then() 是异步的

let p = new Promise(function(resolve, reject){
  resolve("success");
});

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

console.log("which one is called first ?");
输出
"which one is called first ?"
"success"

Promise接收的函数参数是同步执行的,但then方法中的回调函数执行则是异步的,因此,”success”会在后面输出。

3.Promise 三种状态(resolve,reject,pendding)

let p1 = new Promise(function(resolve,reject){
  resolve(1);
});
let p2 = new Promise(function(resolve,reject){
  setTimeout(function(){
    resolve(2);  
  }, 500);      
});
let 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);
}, 1000);
setTimeout(function(){
  console.log(p3);
}, 1000);

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

输出
Promise {[[PromiseStatus]]: "resolved", [[PromiseValue]]: 1}
Promise {[[PromiseStatus]]: "pending", [[PromiseValue]]: undefined}//console执行的时候还没有resolve(2) 所以状态是pending
Promise {[[PromiseStatus]]: "pending", [[PromiseValue]]: undefined}//同上
1
2
3
Promise {[[PromiseStatus]]: "resolved", [[PromiseValue]]: 2}//延迟一秒是最后 0.5秒已经过去已经拿到resolve(2)的执行结果 
Promise {[[PromiseStatus]]: "rejected", [[PromiseValue]]: 3} 同上

Promise有三种状态:pending,resolved,rejected。当Promise刚创建完成时,处于pending状态;返回结果是resolved或者rejected ,因为p1 的函数中执行的是一段同步代码 所以Promise {[[PromiseStatus]]: “resolved”, [[PromiseValue]]: 1}

4.Promise 状态的不可逆性

let p1 = new Promise(function(resolve, reject){
  resolve("p1 success1");
  resolve("p1 success2");
});

let p2 = new Promise(function(resolve, reject){
  resolve("p2 success");
  reject("p2  reject");
});

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

p2.then(function(value){
  console.log(value);
});
输出
"p1 success1"
"p2 success"

Promise状态的一旦变成resolved或rejected时,Promise的状态和值就不会再次改变了,不论你后续再怎么调用resolve或reject方法,都不能改变它的状态和值。因此,p1中resolve(“p1 success2”)并不能将p1的值更改为p1 success2,p2中reject(“p2 reject”)也不能将p2的状态由resolved改变为rejected.
和return 可以一样理解 如果resolved或者rejected 后面的代码就不执行了。

5.链式调用

let p = new Promise(function(resolve, reject){
  resolve(1);
});
p.then(function(value){               //第一个then
  console.log(value);
  return value*2;
}).then(function(value){              //第二个then
  console.log(value);
}).then(function(value){              //第三个then
  console.log(value);
  return Promise.resolve('resolve'); 
}).then(function(value){              //第四个then
  console.log(value);
  throw('reject')
  //return Promise.reject('reject');
}).then(function(value){              //第五个then
  console.log('resolve: '+ value);
}, function(err){
  console.log('reject: ' + err);
})
输出
1
2
undefined //return 返回值问题 没有返回值默认undefined 
"resolve"
"reject: reject"

Promise返回值问题

  1. Promise对象的then方法可以返回一个常数 例如 //第一个then
  2. Promise对象的then方法可以返回一个新的Promise对象 例如 //第三个then
  3. Promise对象的then方法没有返回值 下个接收到的值是undefined //第二个then
  4. 也可以扔出一个异常throw,then方法将返回一个rejected状态的Promise, 值是该异常。

6.Promise 中的异常和 多级then的回调函数

let p1 = new Promise( function(resolve,reject){
  haha();
  resolve( 1 );   
});

p1.then(
  function(value){
    console.log('p1 then value: ' + value);
    return 'p1 1';
  },
  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);
    haha();
  }, 
  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 'p2 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: haha is not defined
p2 then value: 2
p1 then then value: undefined
p2 then then err: ReferenceError: haha is not defined
p2 then then then value: p2 1

Promise中的异常由then参数中第二个回调函数(Promise执行失败的回调)处理,异常信息将作为Promise的值.
p 1 p 2 t h e n P r o m i s e t h e n !

7.Promise.resolve() 返回promise是异步的

let p1 = Promise.resolve( 1 );
let p2 = Promise.resolve( p1 );
let 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,获取p1的状态和值,但这个过程是异步的(不懂可以看下一个例子),

8.定时器和promise

let p1 = new Promise(function(resolve, reject){
    console.log('p1');
    resolve(1);
});

setTimeout(function(){
    console.log('setTimeout');
},0)

p1.then(function(value){
    console.log(value);
})
输出
p1
1
setTimeout

为什么then会优先于定时器先执行是因为等待队列(或者说是任务队列)其实是分为两个: macrotask 和 microtask;promise是存放在microtasks中,而定时器是存放在macrotasks中,但是在每次”事件循环”后会先执行microtask中的内容,并且当这些 microtask 执行结束后还能继续添加 microtask 一直到真个 microtask 队列执行结束,直到当前microtask执行结束之后,才会执行macrotask中的任务,并且往下进行”事件循环”所以才会出现如上代码输出的结果。

如果想详细了解事件队列可以看下 知乎的https://www.zhihu.com/question/36972010 比较详细的解释了为什么会这样 还有V8的源码

猜你喜欢

转载自blog.csdn.net/wen_binobject/article/details/80062311