我我的以爲Promise 函數跟 普羅米修斯很像,都是表明着處理將來的事情的先知。既然能處理將來的事情,那就表明着它擁有很是的能力,聽我慢慢吹來呀~ 首先來看看官方的吹牛文檔解釋:ajax
所謂Promise,簡單說就是一個容器,裏面保存着某個將來纔會結束的事件(一般是一個異步操做)的結果。從語法上說,Promise 是一個對象,從它能夠獲取異步操做的消息。Promise 提供統一的 API,各類異步操做均可以用一樣的方法進行處理。json
你看沒錯吧,是否是很像一個先知能夠處理將來的事情?既然是神仙確定是我們凡人管不了的,爲啥管不了那?就體如今它三個內部狀態上:api
對象的狀態不受外界影響。Promise對象表明一個異步操做,有三種狀態:pending(進行中)、fulfilled(已成功)和rejected(已失敗)只有異步操做的結果,能夠決定當前是哪種狀態,任何其餘操做都沒法改變這個狀態。這也是Promise這個名字的由來,它的英語意思就是「承諾」,表示其餘手段沒法改變。數組
看見了嗎,敲黑板劃重點,神仙已經決定的東西就不能改變。並且一旦new Promise對象就不能取消,講究~promise
那如何使用那?下面來看一個簡單的例子:bash
const promise = new Promise (function(resolve, reject) { //這是先知啊,先知
if (/* 異步操做成功 */){
resolve(value); // resolve就是這事兒先知贊成了,你就幹就完了
} else {
reject(error); // reject就是這事兒先知不一樣意,白b扯了
}
});
複製代碼
注意上面的事情其實有沒有發生?沒有,先知嘛預知將來的事情,何時發生那?固然先知贊成的時候也就是說狀態變成resolved。只要一resolved 立刻就能夠then了,劃重點 敲黑板 then 就是這玩意。app
promise.then(function(value) {
// 妥妥的這個已經辦了,下面你想咋地吧?能夠連式操做無限then下去
}, function(error) {
// 失敗了消停的把錯誤信息打出來把
console.log("錯誤信息:"+error)
});
複製代碼
那麼坑人的玩意來了,請看下面代碼,誰先打印?異步
let promise = new Promise(function(resolve, reject) {
console.log('Promise');
resolve();
});
promise.then(function() {
console.log('resolved.');
});
console.log('Hi!');
複製代碼
上面代碼中,Promise 新建後當即執行,因此首先輸出的是Promise。而後,then方法指定的回調函數,將在當前腳本全部同步任務執行完纔會執行,因此resolved最後輸出。那麼接下來這段 函數
概念吹完了,來看勢力post
妥了,接下來看一個用Promise對象實現的 Ajax 操做的實例:
const getJSON = function(url) {
const promise = new Promise(function(resolve, reject){
const handler = function() {
if (this.readyState !== 4) {
return;
}
if (this.status === 200) {
resolve(this.response);
} else {
reject(new Error(this.statusText));
}
};
const client = new XMLHttpRequest();
client.open("GET", url);
client.onreadystatechange = handler;
client.responseType = "json";
client.setRequestHeader("Accept", "application/json");
client.send();
});
return promise;
};
getJSON("/posts.json").then(function(json) {
console.log('Contents: ' + json);
}, function(error) {
console.error('出錯了', error);
});
複製代碼
是否是很簡單,一點都不難,只是把ajax的操做流程放到了先知的內部,讓先知幫你獲取各類成功失敗的狀態!結合實際,咱們在工做中可能一次要請求好幾個接口的數據,Promise提供了一個更加簡單的方法
const p = Promise.all([p1, p2, p3]);
複製代碼
很好理解,all 的參數表明這一個可執行的任務隊列,只要裏面有任務就能夠往下執行,也就是我們訪問的多個api集合組成的數組。
// 生成一個Promise對象的數組
const promises = [2, 3, 5, 7, 11, 13].map(function (id) {
return getJSON('/post/' + id + ".json"); //ID 做爲參數 變成動態請求
});
Promise.all(promises).then(function (posts) {
// ...
}).catch(function(reason){
// ...
});
複製代碼
還有一個相似 all的api Promise.race,Promise.race方法的參數與Promise.all方法同樣,若是不是 Promise 實例,就會先調用下面講到的Promise.resolve方法,將參數轉爲 Promise 實例,再進一步處理
const p = Promise.race([
fetch('/resource-that-may-take-a-while'),
new Promise(function (resolve, reject) {
setTimeout(() => reject(new Error('request timeout')), 5000)
})
]);
p
.then(console.log)
.catch(console.error);
複製代碼
上面代碼中,若是 5 秒以內fetch方法沒法返回結果,變量p的狀態就會變爲rejected,從而觸發catch方法指定的回調函數。
妥妥滴,既然到這裏我估計你應該懂了,其實任何技術都不難,都能拆分紅若干個簡單點。任意簡單的點組合起來就又複雜了,正所謂大道至簡,相信萬事萬物都是簡單的原理,懷着敬畏的心理去學習,終究會獲得本身的收穫。