Promise快速入門

週五就想寫這篇文章,可是無奈花花世界的誘惑太多……就一直拖到了今天,自責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...

相關文章
相關標籤/搜索