Node的產生,大大推進了Javascript這門語言在服務端的發展,使得前端人員能夠以很低的門檻轉向後端開發。 固然,這並不表明迸發成了全棧。全棧的技能很集中,毫不僅僅是前端會寫一些HTML和一些交互,後臺熟悉數據庫的增刪查改。css
想必接觸過Node的人都知道,Node是以異步(Async)回調著稱的,其異步性提升了程序的執行效率,但同時也減小了程序的可讀性。若是咱們有幾個異步操做,而且後一個操做須要前一個操做返回的數據才能執行,這樣按照Node的通常執行規律,要實現有序的異步操做,一般是一層加一層嵌套下去。 爲了解決這個問題,ES6提出了Promise的實現。html
含義 Promise 對象用於一個異步操做的最終完成(或失敗)及其結果值的表示。簡單點說,它就是用於處理異步操做的,異步處理成功了就執行成功的操做,異步處理失敗了就捕獲錯誤或者中止後續操做。 它的通常表示形式爲:前端
new Promise(
/* executor */
function(resolve, reject) {
if (/* success */) {
// ...執行代碼
resolve();
} else { /* fail */
// ...執行代碼
reject();
}
}
);
複製代碼
其中,Promise中的參數executor是一個執行器函數,它有兩個參數resolve和reject。它內部一般有一些異步操做,若是異步操做成功,則能夠調用resolve()來將該實例的狀態置爲fulfilled,即已完成的,若是一旦失敗,能夠調用reject()來將該實例的狀態置爲rejected,即失敗的。vue
咱們能夠把Promise對象當作是一條工廠的流水線,對於流水線來講,從它的工做職能上看,它只有三種狀態,一個是初始狀態(剛開機的時候),一個是加工產品成功,一個是加工產品失敗(出現了某些故障)。一樣對於Promise對象來講,它也有三種狀態:node
var promise1 = new Promise(function(resolve, reject) {
// 2秒後置爲接收狀態
setTimeout(function() {
resolve('success');
}, 2000);//歡迎加入全棧開發交流圈一塊兒學習交流:864305860
});//面向1-3年前端人員
//幫助突破技術瓶頸,提高思惟能力
promise1.then(function(data) {
console.log(data); // success
}, function(err) {
console.log(err); // 不執行
}).then(function(data) {
// 上一步的then()方法沒有返回值
console.log('鏈式調用:' + data); // 鏈式調用:undefined
}).then(function(data) {
// ....
});
複製代碼
咱們主要關注promise1.then()方法調用後返回的Promise對象的狀態,是pending仍是fulfilled,或者是rejected?webpack
var promise2 = new Promise(function(resolve, reject) {
// 2秒後置爲接收狀態
setTimeout(function() {
resolve('success');
}, 2000);
});
promise2
.then(function(data) {
// 上一個then()調用了resolve,置爲fulfilled態
console.log('第一個then');
console.log(data);
return '2';
})
.then(function(data) {
// 此時這裏的狀態也是fulfilled, 由於上一步返回了2
console.log('第二個then');
console.log(data); // 2
return new Promise(function(resolve, reject) {
reject('把狀態置爲rejected error'); // 返回一個rejected的Promise實例
});
}, function(err) {
// error
})//歡迎加入全棧開發交流圈一塊兒學習交流:864305860
.then(function(data) {
/* 這裏不運行 */
console.log('第三個then');
console.log(data);
// ....
}, function(err) {
// error回調
// 此時這裏的狀態也是fulfilled, 由於上一步使用了reject()來返回值
console.log('出錯:' + err); // 出錯:把狀態置爲rejected error
})//歡迎加入全棧開發交流圈一塊兒學習交流:864305860
.then(function(data) {
// 沒有明確指定返回值,默認返回fulfilled
console.log('這裏是fulfilled態');
});//歡迎加入全棧開發交流圈一塊兒學習交流:864305860
複製代碼
Promise.prototype.catch() catch()方法和then()方法同樣,都會返回一個新的Promise對象,它主要用於捕獲異步操做時出現的異常。所以,咱們一般省略then()方法的第二個參數,把錯誤處理控制權轉交給其後面的catch()函數,以下:web
var promise3 = new Promise(function(resolve, reject) {
setTimeout(function() {
reject('reject');
}, 2000);
});
promise3.then(function(data) {
console.log('這裏是fulfilled狀態'); // 這裏不會觸發
// ...
}).catch(function(err) {
// 最後的catch()方法能夠捕獲在這一條Promise鏈上的異常
console.log('出錯:' + err); // 出錯:reject
});
複製代碼
Promise.all() Promise.all()接收一個參數,它必須是能夠迭代的,好比數組。 它一般用來處理一些併發的異步操做,即它們的結果互不干擾,可是又須要異步執行。它最終只有兩種狀態:成功或者失敗。 它的狀態受參數內各個值的狀態影響,即裏面狀態所有爲fulfilled時,它纔會變成fulfilled,不然變成rejected。 成功調用後返回一個數組,數組的值是有序的,即按照傳入參數的數組的值操做後返回的結果。以下:面試
// 置爲fulfilled狀態的狀況
var arr = [1, 2, 3];
var promises = arr.map(function(e) {
return new Promise(function(resolve, reject) {
resolve(e * 5);
});
});
Promise.all(promises).then(function(data) {
// 有序輸出
console.log(data); // [5, 10, 15]
console.log(arr); // [1, 2, 3]
});
複製代碼
// 置爲rejected狀態的狀況
var arr = [1, 2, 3];
var promises2 = arr.map(function(e) {
return new Promise(function(resolve, reject) {
if (e === 3) {
reject('rejected');
}//歡迎加入全棧開發交流圈一塊兒學習交流:864305860
resolve(e * 5);//面向1-3年前端人員
});//幫助突破技術瓶頸,提高思惟能力
});
Promise.all(promises2).then(function(data) {
// 這裏不會執行
console.log(data);
console.log(arr);
}).catch(function(err) {
console.log(err); // rejected
});
複製代碼
Promise.race() Promise.race()和Promise.all()相似,都接收一個能夠迭代的參數,可是不一樣之處是Promise.race()的狀態變化不是所有受參數內的狀態影響,一旦參數內有一個值的狀態發生的改變,那麼該Promise的狀態就是改變的狀態。就跟race單詞的字面意思同樣,誰跑的快誰贏。以下:數據庫
var p1 = new Promise(function(resolve, reject) {
setTimeout(resolve, 300, 'p1 doned');
});
//歡迎加入全棧開發交流圈一塊兒學習交流:864305860
var p2 = new Promise(function(resolve, reject) {
setTimeout(resolve, 50, 'p2 doned');
});
//歡迎加入全棧開發交流圈一塊兒學習交流:864305860
var p3 = new Promise(function(resolve, reject) {
setTimeout(reject, 100, 'p3 rejected');
});
//歡迎加入全棧開發交流圈一塊兒學習交流:864305860
Promise.race([p1, p2, p3]).then(function(data) {
// 顯然p2更快,因此狀態變成了fulfilled
// 若是p3更快,那麼狀態就會變成rejected
console.log(data); // p2 doned
}).catch(function(err) {
console.log(err); // 不執行
});
複製代碼
Promise.resolve() Promise.resolve()接受一個參數值,能夠是普通的值,具備then()方法的對象和Promise實例。正常狀況下,它返回一個Promise對象,狀態爲fulfilled。可是,當解析時發生錯誤時,返回的Promise對象將會置爲rejected態。以下:後端
// 參數爲普通值
var p4 = Promise.resolve(5);
p4.then(function(data) {
console.log(data); // 5
});
// 參數爲含有then()方法的對象
var obj = {
then: function() {
console.log('obj 裏面的then()方法');
}
};
var p5 = Promise.resolve(obj);
p5.then(function(data) {
// 這裏的值時obj方法裏面返回的值
console.log(data); // obj 裏面的then()方法
});
// 參數爲Promise實例
var p6 = Promise.resolve(7);
var p7 = Promise.resolve(p6);
p7.then(function(data) {
// 這裏的值時Promise實例返回的值
console.log(data); // 7
});
// 參數爲Promise實例,但參數是rejected態
var p8 = Promise.reject(8);
var p9 = Promise.resolve(p8);
p9.then(function(data) {
// 這裏的值時Promise實例返回的值
console.log('fulfilled:'+ data); // 不執行
}).catch(function(err) {
console.log('rejected:' + err); // rejected: 8
});//歡迎加入全棧開發交流圈一塊兒學習交流:864305860
複製代碼
Promise.reject() Promise.reject()和Promise.resolve()正好相反,它接收一個參數值reason,即發生異常的緣由。此時返回的Promise對象將會置爲rejected態。以下:
var p10 = Promise.reject('手動拒絕');
p10.then(function(data) {
console.log(data); // 這裏不會執行,由於是rejected態
}).catch(function(err) {
console.log(err); // 手動拒絕
}).then(function(data) {
// 不受上一級影響
console.log('狀態:fulfilled'); // 狀態:fulfilled
});//歡迎加入全棧開發交流圈一塊兒學習交流:864305860
複製代碼
除非Promise.then()方法內部拋出異常或者是明確置爲rejected態,不然它返回的Promise的狀態都是fulfilled態,即完成態,而且它的狀態不受它的上一級的狀態的影響。 結語
感謝您的觀看,若有不足之處,歡迎批評指正。
本次給你們推薦一個免費的學習羣,裏面歸納移動應用網站開發,css,html,webpack,vue node angular以及面試資源等。 對web開發技術感興趣的同窗,歡迎加入Q羣:864305860,無論你是小白仍是大牛我都歡迎,還有大牛整理的一套高效率學習路線和教程與您免費分享,同時天天更新視頻資料。 最後,祝你們早日學有所成,拿到滿意offer,快速升職加薪,走上人生巔峯。