週五就想寫這篇文章,可是無奈花花世界的誘惑太多……就一直拖到了今天,自責1e4遍;
進入正題Promise
:vue
Promise 對象用於表示一個異步操做的最終狀態(完成或失敗),以及其返回的值。
上爲MDNPromise
的定義;
ES6規定Promise
是一個構造函數,用來生成Promise
實例(就是跟new一個女友同樣);Promise
意爲‘承諾’,承諾是發生在將來且必須達成的事,對應Promise
對象是一個保存着將來纔會結束的異步操做的「容器」;es6
Promise
對象表明的異步操做有三個狀態:promise
pending
(進行中)fulfilled
(已成功)rejected
(已失敗)Promise
對象有一下兩個特色:app
Promise
對象的狀態,即承諾這個詞的由來,也表現了程序猿的浪漫~~const promise = new Promise(function(resolve, reject) { // ... some code 當即執行 if (/* 異步操做成功 */){ resolve(value);// 將狀態改成fulfilled 並將參數傳遞給then中的回調函數 } else { reject(error);// 將狀態改成rejected 並將參數傳遞給then/catch中的回調函數 } }); // then方法接受兩個參數分別對應兩個狀態的處理,其中對應rejected的參數可選,兩個參數都接受上面promise對象傳出的參數做爲參數 promise.then(function(value) { // success 成功處理 }, function(error) { // failure 錯誤處理 });
瞭解了基本用法咱們來了解一下Promise
到底有啥用啊,個人理解就是以同步的方式(鏈式調用)去處理異步操做(回調),在這個Promise
對象出現以前咱們是怎麼處理異步操做的呢?
舉個栗子~:異步
console.log('start'); setTimeout(function (name) { var fruitList = name + ','; setTimeout(function (name) { fruitList += name + ','; setTimeout(function (name) { fruitList += name + ','; setTimeout(function (name) { fruitList += name + ','; setTimeout(function (name) { fruitList += name; console.log(fruitList); }, 1, '西瓜'); }, 1, '香蕉'); }, 1, '橘子'); }, 1, '蘋果');}, 1, '葡萄'); console.log('上面是個異步過程,因此我先出來,後面纔是水果');
我這裏只是簡單的寫了幾層簡單的定時器而已,若是要不少不少層而且稍微複雜一點的回調函數就很難以維護了且代碼閱讀很難受。因此Promise
的出現就是爲了鏈式的調用來實現這種異步操做一樣以本例改成Promise
的方式來一遍~:函數
console.log('start'); var promise1 = new Promise((resolve,reject)=>{ setTimeout(resolve('葡萄'),1); }); promise1.then(value=>new Promise((resolve,reject)=>setTimeout(resolve(value+',蘋果'),1))) .then(value=>new Promise((resolve,reject)=>setTimeout(resolve(value+',橘子'),1))) .then(value=>new Promise((resolve,reject)=>setTimeout(resolve(value+',香蕉'),1))) .then(value=>new Promise((resolve,reject)=>setTimeout(resolve(value+',西瓜'),1))) .then(value=>{console.log(value)}); console.log('上面是個異步過程,因此我先出來,後面纔是水果');
其實本例中的reject參數能夠省略,由於我默認他確定會成功的了,額還有就是寫function
比較麻煩這裏直接用了箭頭函數~~恩……在科普一個小坑給大家,若是在vue
中使用promise
用箭頭函數要比寫function
舒服不少,function
中this指向的是window
而不是vue
實例~學習
再來看看下面這個拋出錯誤的相關栗子:ui
console.log("start"); new Promise((resolve, reject) => { var data = [1,2,3,4,5,6,7]; return resolve(data); }) .then((result) => { var newResult = result.slice(1); return newResult; }) .then((result)=>{ console.log(result); throw new Error('someting error'); }) .catch((value)=>{ console.log(value);// 拋出錯誤以後 執行catch操做 接受的參數是拋出的錯誤,其實.catch只是Promise.then(reject)的別名而已 }) .then((value) => { console.log(value);// undefined 拋出錯誤後沒有 return 因此這裏是個undefined console.log('我任性,錯了以後仍要執行');// catch以後仍然能夠繼續執行then操做 });
註釋上寫的很清楚咯~~this
接下來在來個實際點的用法異步加載圖片(原諒我實際上是從阮一峯老師那裏偷來的栗子吃):url
function loadImageAsync(url){ return new Promise((resolve,reject)=>{ var image = new Image(); image.onload = function(){ resolve(image); } image.onerror = function(){ reject(new Error('不能加載圖片,url是'+ url)); } image.src = url; }); } loadImageAsync('QQ圖片20171114220539.png').then(value =>{ console.log(value); document.body.append(value); });
因爲最近確實是忙得頭昏腦脹,就先簡單的分享一波基礎用法,剩下的關於promise的兩種模式Promise.all()
和Promise.race()
等我改天再加或者另發一篇吧
一樣你也能夠去這裏學習瞭解一下:http://es6.ruanyifeng.com/#do...