一:先看第一段代碼:
var 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)
})
由輸出可以看出,newPromise的函數參數是立即執行的。
二:第二段代碼: 存在異步函數時的執行順序。
var p1 = new Promise(function(resolve,reject){ //參數函數立即執行,轉化爲resolved狀態
resolve(1);
});
var p2 = new Promise(function(resolve,reject){ //參數函數是異步函數,所以稍後執行,導致控制檯輸出時,狀態還是pendding
setTimeout(function(){
resolve(2);
},500)
})
var p3 = new Promise(function(resolve,reject){ //參數函數是異步函數,所以稍後執行,導致控制檯輸出時,狀態還是pendding
setTimeout(function(){
reject(3)
},500)
})
console.log(p1) //狀態resolved
console.log(p2) //狀態pendding
console.log(p3) //狀態pendding
setTimeout(function(){ //最後輸出 狀態已經由pendding轉化爲resolve
console.log(p2);
},1000)
setTimeout(function(){ //最後輸出 狀態已經由pendding轉化爲reject
console.log(p3);
},1000);
p1.then(function(value){
console.log('then p1:----'+value) //到這一步說明異步函數已經執行完畢,狀態resolved
})
p2.then(function(value){ //到這一步說明異步函數已經執行完畢,狀態resolved
console.log('then p2:----'+value)
})
p3.catch(function(err){ //到這一步說明異步函數已經執行完畢,狀態reject
console.log('then p3:----'+err)
})
輸出結果:
三:promise的鏈式調用
var p = new Promise(function(resolve,reject){
resolve(1);
});
p.then(function(value){
console.log('第一個then:---'+value); //值爲1
return value * 2
}).then(function(value){
console.log('第二個then:---'+value); //值爲1*2=2
//注意第二個then沒有return 所以默認return undefined
}).then(function(value){
console.log('第三個then:---'+value); //值爲undefined
return Promise.resolve('resolve'); //可以在then函數中新創建promise對象並返回
}).then(function(value){
console.log('第四個then:---'+value); //值爲resolve
return Promise.reject('reject'); //返回reject狀態的promise
}).then(function(value){
console.log('第五個then:---'+'resolve:'+value);
},function(err){
console.log('最後一個回調函數err--reject:'+err) //由第二個回調函數進行處理 值爲reject
})
關於then的鏈式調用,如果then沒有return值,那麼默認就是返回值就是undefined,並且在then函數中隨時可以改變promise的狀態。
四:promise的異常
//Promise中的異常
var p1 = new Promise(function(resolve,reject){ //立即執行函數
foo.bar(); //報錯
resolve(1);
});
p1.then(function(value){
console.log('p1-第一then-resolve----'+value);
},function(err){ //then的第二個參數處理 foo is not defined
console.log('p1-第一then-err----'+err);
}).then(function(value){ //第三步,錯誤處理後promise已經正常,下面又由resolve處理,因爲沒有返回值,所以undefined
console.log('p1-第二then-resolve----'+value); //值爲 undefined
},function(err){
console.log('p1-第二then-err----'+err);
});
var p2 = new Promise(function(resolve,reject){
resolve(2);
});
p2.then(function(value){
console.log('p2 第一then resolve-----'+value); //第二步執行的是它 值爲 2
foo.bar(); //報錯
},function(err){
console.log('p2第一then err'+ err);
}).then(function(value){
console.log('p2 第二then resolve-----'+value);
},function(err){ //上面報錯交給err處理 , 並返回1
console.log('p2第二then err'+ err);
return 1
}).then(function(value){ //錯誤處理後promise正常,由resolve進行邏輯執行,
console.log('p2 第三then resolve-----'+value); //值爲 返回值 1
},function(err){
console.log('p2 第三then err'+ err);
})
由輸出可以得出以下結論,第一:newPromise的傳遞函數是立即執行的,第二:異常處理後promise的狀態就會變爲resolve。第三:then函數正常情況下是依次交替執行。
五:創建promise的幾種方式
Promise.resolve() //可以接受一個值 , 這時返回一個resolved狀態的promise對象,並且該對象的值爲傳遞的參數
var p1 = Promise.resolve( 1 ); //1就是該promise對象的值
Promise.resolve() //也可以接受一個Promise對象 ,這時直接返回這個promise參數 也就是直接返回 p1 於是p1===P2
var p2 = Promise.resolve( p1 );
var p3 = new Promise(function(resolve, reject){ //new方法創建的都是新對象,所以都不相等
resolve(1);
});
var p4 = new Promise(function(resolve, reject){
resolve(p1);
});
console.log(p1 === p2); //true
console.log(p1 === p3); //false
console.log(p1 === p4); //false
console.log(p3 === p4); //false
p4.then(function(value){
console.log('p4=' + value);
});
p1.then(function(value){
console.log('p1=' + value);
})
p2.then(function(value){
console.log('p2=' + value);
})
結論,第一:通過newPromise創建的promise對象都是不同的,第二:通過Promise創建promise對象有兩種傳參方式:1,直接傳遞新創建的promise的值eg:Promise.resolve(1). 2:參數直接爲promise對象,Promise.resolve(p1),這種情況返回值就是p1這個promise對象。
六: newPromise()的兩個參數函數,resolve, reject
var p1 = new Promise(function(resolve, reject){
resolve(Promise.resolve('resolve')); //第一個參數resolve會對promise對象進行拆箱,獲得promise對象和值,這個過程是異步的
});
var p2 = new Promise(function(resolve, reject){
resolve(Promise.reject('reject'));
});
var p3 = new Promise(function(resolve, reject){
reject(Promise.resolve('resolve')); // 第二個參數沒有拆箱功能,所以直接將參數傳遞給then方法中的reject回調,
});
p1.then(
function fulfilled(value){
console.log('fulfilled: ' + value);
},
function rejected(err){
console.log('rejected: ' + err);
}
);
p2.then(
function fulfilled(value){
console.log('fulfilled: ' + value);
},
function rejected(err){
console.log('rejected: ' + err);
}
);
p3.then(
function fulfilled(value){
console.log('fulfilled: ' + value);
},
function rejected(err){
console.log( err); //所以直接打印一個Promise對象
}
);
結論: rosolve參數具有拆箱能力,並且該工程是異步的,所以打印輸出順序靠後,reject參數不具備拆箱能力,所以直接輸出傳遞的參數,這樣p3.then輸出的就是狀態爲resolve的promise對象。