原文: 爲什麼要使用promise
起因
大家都知道做前端開發最讓人頭痛的就是處理異步請求的情況,在請求到的成功回調函數裏繼續寫函數,長此以往形成了回調地獄。
function load() {
$.ajax({
url: 'xxx.com',
data: 'jsonp',
success: function(res) {
init(res, function(res) {
render(res, function(res) {
// 一層一層又一層
});
});
}
}
}
load();
這樣的代碼層級少當然還是可以湊合看的,但是多起來的話,就難以維護了,無論是開發者自身還是同事來接手項目,都是極其無奈的!還要我怎樣,要怎樣,怎樣,樣。
於是乎 出現了Promise
當年在聽到關於Promise的報道的時候沒有太多關注,只知道是解決回調地獄問題的,一種異步請求解決方案。 後來在工作當中發現JQ也實現了相關的方法,上代碼
$.get('xxx.php').done(function() {
alert('成功的回調'); // 相當於Promise的resolve()
});
現在看來,真的和Promise差不多呢。那麼我們回到今天的主角來
先介紹一下Promise的三種狀態:
- Pending 進行中
- Fulfilled 已成功
- Rejected 已失敗
說完了狀態直接上代碼,我們得會用才行:
還以上面load函數的例子
// then方法是用的最多的了
// 按照then來執行成功和失敗的回調函數
function load() {
return new Promise((resovel, reject) => {
$.ajax({
url: 'xxx.com',
data: 'jsonp',
success: function(res) {
resolve(res);
},
error: function(err) {
reject(err);
}
});
});
}
// 用一下
load().then(data => {
console.log(data); // 請求到的數據
console.log('請求數據成功');
}, err => {
console.log('請求失敗');
});
除了處理請求,Promise還可以寫在普通的函數中
function init(options) {
return new Promise((resolve, reject) => {
if (options.id) {
console.log('你是唯一')
resolve(options.id);
} else {
console.log('不行,不行');
reject()
}
});
}
init({id: 110})
.then(id => {
console.log(id); // 110
let obj = {id, nickname: '左夕'};
return obj;
})
.then(other => {
console.log(other); // { id: 110, nickname: '左夕' }
});
Promise.all和Promise.race有點類似
all 是 Promise 的狀態都爲成功才表示成功
race 是 Promise 的狀態有一個先成功的狀態,就表示成功
最近很火的axios其實就是調用了Promise,寫法也是很相似的
由於它是第三方包,需要npm i axios安裝一下
// 發個get請求
axios.get('user/', {
id,
username
}).then(res => {
console.log(res); // 成功
}).catch(err => {
console.log(err); // 失敗
});
// 再來個post請求
axios.post('login/', {
username,
password
}).then(res => {
console.log(res); // 成功
}).catch(err => {
console.log(err); // 失敗
});
// 也有all的操作
function getUser() {
return axios.get('/user');
}
function sendMsg() {
return axios.post('/info', {msg});
}
axios.all([getUser(), sendMsg()]).then(res => {})
總結一下:Promise常用的就是這些了,then返回的也是一個Promise對象,所以可以繼續調用.then方法。