學習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)
})

執行結果:javascript

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

promise三種狀態

未完成態pending,完成態resolved,失敗態rejectedjava

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

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
})

執行結果:code

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);
  }
)

執行結果:ip

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執行成功的回調函數處理。另外,須要注意p一、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吧???

相關文章
相關標籤/搜索