ES6 promise

回調與promise
方法 用於請求數據(模擬)
resolve表明成功時要作的事情html

    function f() {
        return new Promise(resolve => {
            setTimeout(function() {
                resolve();
            }, 1000);
        })
    }

    f()
        .then(function() {
            console.log(1);
            //return promise實例,才能繼續.then()
            return f();
        })
        .then(function() {
            console.log(2);
            return f();
        })
        .then(function() {
            console.log(4);
            return f();
        })
        .then(function() {
            console.log(3);
            return f();
        })
        .then(function() {
            console.log(5);
            return f();
        })
        .then(function() {
            console.log(6);
        });

案例:
Promise 新建後當即執行,因此首先輸出的是Promise,而後,then方法指定的回調函數,將在當前腳本全部同步任務執行完纔會執行,因此resolved最後輸出數組

    let promise=new Promise(resolve=>{
        console.log('Promise');
        resolve();
    });

    promise.then(function(){
        console.log('resolved');
    });

    console.log('Hello!');
    //結果:Promise Hello! resolved

Promise小動畫案例:
index.htmlpromise

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <style>
    #el {
      width: 100px;
      background: green;
      transition: all 1s;
      color: white;
      line-height: 100px;
      text-align: center;
      font-size: 40px;
    }
  </style>
</head>
<body>
  <div id="el"></div>
  <button id="btn">開始</button>
  <script src="./main.js"></script>
</body>
</html>

main.jsapp

function moveTo(el, x, y) {
    return new Promise(resolve => {
        el.style.transform = `translate(${x}px, ${y}px)`;
        setTimeout(function() {
            resolve();
        }, 1000);
    });
}

let el = document.querySelector('div');

document.querySelector('button').addEventListener('click', e => {
    moveTo(el, 100, 100)
        .then(function() {
            console.log('第一次移動');
            return moveTo(el, 200, 200);
        })
        .then(function() {
            console.log('第二次移動');
        })
        .then(function() {
            console.log('第二次移動');
        });
});

錯誤處理
resolve成功時操做
reject失敗時操做異步

  function f(val) {
    return new Promise((resolve, reject) => {
      if (val) {
        resolve({ name: '小明' });
      } else {
        reject('404');
      }
    }); 
  }

  f(true)
    .then((data) => {
      console.log(data)
    }, e => {
      console.log(e);
    })

catch
使用實例的catch方法 能夠捕獲錯誤函數

    f(true)
      .then(data => {
        console.log(data);
        return f(false);
      })
      .then(() => {
        console.log('我永遠不會被輸出');
      })
      .then(() => {

      })
      .catch(e => {
        console.log(e);
        return f(false) ;
      });

finally
不論成功仍是失敗 finally中的內容必定會執行動畫

   f(true)
      .then(data => {
        console.log(data);
        return f(false);
      })
      .catch(e => {
        console.log(e);
        return f(false);
      })
      .finally(() => {
        console.log(100);
      });

promise三種狀態
pending 進行中
fulfilled 成功
rejected 失敗
狀態的改變不可逆:
pending能夠到fulfilled或者rejectedui


 

Promise.all方法能夠把多個promise實例 包裝成一個新的promise實例
Promise.all([ promise1, promise2 ]) : Promise
模擬須要多個請求的數據 才能進行下一步操做的狀況spa

    function getData1() {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          console.log('第一條數據加載成功');
          resolve('data1');
        }, 1000);
      });
    }
    function getData2() {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          console.log('第二條數據加載成功');
          resolve('data2');
        }, 1000);
      });
    }
    function getData3() {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          console.log('第三條數據加載成功');
          resolve('data3');
        }, 1000);
      });
    }
    function getData4() {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          console.log('第四條數據加載成功');
          resolve('data4');
        }, 2000);
      });
    }
    // 全部數據都成功,則總決議成功,並返回全部成功提示
    let p = Promise.all([getData1(),getData2(),getData3(),getData4()]);
    p.then(arr => {
      console.log(arr);
    });

一條數據失敗,則總決議失敗,並返回錯誤信息code

    function getData1() {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          console.log('第一條數據加載成功');
          resolve('data1');
        }, 1000);
      });
    }
    function getData2() {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          console.log('第二條數據加載成功');
          resolve('data2');
        }, 1000);
      });
    }
    function getData3() {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          console.log('第三條數據加載成功');
          resolve('data3');
        }, 1000);
      });
    }
    function getData4() {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          reject('data4 err');
        }, 500);
      });
    }
    // 一條數據失敗,則總決議失敗,並返回錯誤信息
    let p = Promise.all([getData1(),getData2(),getData3(),getData4()]);
    p.then(arr => {
      console.log(arr);
    },e=>{
        console.log(e);
    });

空數組直接決議爲成功

    function getData1() {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          console.log('第一條數據加載成功');
          resolve('data1');
        }, 1000);
      });
    }
    function getData2() {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          console.log('第二條數據加載成功');
          resolve('data2');
        }, 1000);
      });
    }
    function getData3() {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          console.log('第三條數據加載成功');
          resolve('data3');
        }, 1000);
      });
    }
    function getData4() {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          reject('data4 err');
        }, 500);
      });
    }
    // 空數組直接決議爲成功
    let p = Promise.all([]);
    p.then(() => {
      console.log('null');
    },e=>{
        console.log(e);
    });

promise.race
只要有一個決議爲成功或者失敗,就會返回

  function getData1() {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        console.log('第一條數據加載成功');
        reject('err');
      }, 500);
    });
  }
  function getData2() {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        console.log('第二條數據加載成功');
        resolve('data2');
      }, 1000);
    });
  }
  function getData3() {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        console.log('第三條數據加載成功');
        resolve('data3');
      }, 1000);
    });
  }

  let p = Promise.race([getData1(),getData2(),getData3()]);

  p.then(data => {
      console.log(data);
  }, e => {
      console.log(e);
  })

空數組會被掛起

  let p = Promise.race([]);

Promise.resolve() 和 Promise.reject()
經常使用來生成已經被決議爲失敗或者成功的promise實例


 

Promise.resolve傳遞一個普通的值
決議成功並把值傳遞過去

    let p1 = new Promise(resolve => {
      resolve('成功!');
    });
    let p2 = Promise.resolve('成功!');

Promise.resolve傳遞一個promise實例

    let poruomiesi = new Promise(resolve => {
      resolve('耶!')
    });
    // 直接返回傳遞進去的promise
    let p = Promise.resolve(poruomiesi);
    p.then(data => void console.log(data));
    console.log(p === poruomiesi); 

Promise.resolve傳遞一個thenable
若是傳遞的是個thenable

    let obj = {
      then(cb) {
        console.log('我被執行了');
        cb('哼!');
      },
      oth() {
        console.log('我被拋棄了');
      }
    }
    // 當即執行then方法
    Promise.resolve(obj).then(data => {
      console.log(data);
    });

Promise.reject
直接決議爲失敗,不作處理

    Promise.reject({ then() { console.log(1) } })
      .then(() => {
        console.log('我不會被執行');
      }, e => {
        console.log(e);
      });

異步任務老是在同步任務以後執行
把同步的任務轉成異步任務

    function createAsyncTask(syncTask) {
      return Promise.resolve(syncTask).then(syncTask => syncTask());
    }
    createAsyncTask(() => {
      console.log('我變成了異步任務!!!');
      return 1 + 1;
    }).then(res => {
      console.log(res);
    });
    console.log('我是同步任務!');

要求:多張圖片加載完以後才能進行統一展現

    const loadImg = src => {
        return new Promise((resolve, reject) => {
            const img = new Image();
            img.src = src;
            img.onload=()=>{
                resolve(img);
            };
            img.onerror=(e)=>{
                reject(e);
            };
            // img.onload = void resolve(img);
            // img.onerror = void reject('加載失敗');
        });
    };

    const imgs = [
        'http://img1.sycdn.imooc.com\/climg/5b16558d00011ed506000338.jpg',
        'http://img1.sycdn.imooc.com\/climg/5b165603000146ca06000338.jpg',
        'http://img1.sycdn.imooc.com//climg/5b1656140001c89906000338.jpg'
    ];

    // map遍歷數組中的每一項
    Promise.all(imgs.map(src => loadImg(src))).then(arr => {
        console.log(arr);
        arr.forEach((img)=>{
            document.body.appendChild(img);
        });
    });
    // map遍歷數組中的每一項(與上面相同做用,上面是簡寫)
    // map進行循環,每循環一次就將src做爲參數傳遞進來
    // const promises=imgs.map(src =>{
    //     return loadImg(src);
    // });
    // Promise.all(promises).then(arr => {
    //     console.log(arr);
    //     arr.forEach((img)=>{
    //         document.body.appendChild(img);
    //     });
    // }).catch((e)=>{
    //     console.log(e);
    // });
相關文章
相關標籤/搜索