整理筆記--Promise

Promise 是異步編程的一種解決方案。javascript

Promise對象兩個特色:

對象的狀態不受外界影響。Promise對象表明一個異步操做,有三種狀態:pending(進行中)、fulfilled(已成功)和rejected(已失敗)。只有異步操做的結果,能夠決定當前是哪種狀態,任何其餘操做都沒法改變這個狀態。java

一旦狀態改變,就不會再變。稱爲 resolved[已定型]。
從pending變爲fulfilled 或者 從pending變爲rejectedes6

Promise缺點:

沒法取消 Promise ,一旦新建它就會當即執行,沒法中途取消。
若是不設置回調函數,Promise 內部拋出的錯誤,不會反應到外部。
當處於 pending 狀態時,沒法得知目前進展到哪個階段(剛剛開始仍是即將完成)。編程

1、基礎用法

//新建promise對象   兩個參數resolve, reject
const promise = new Promise(function(resolve, reject) {
  if (/* 異步操做成功 */){
    resolve(value);
  } else {
    reject(error);
  }
});


promise
.then( //promise的resolved回調函數
    result => {console.log("resolved: ", result)},  //then的第一方法成功回調,
    err => console.log("rejected: ", err)  //then的第二個失敗回調 (可選) 不推薦 更推薦在catch捕獲錯誤
.catch(error => {···}) //promise的resolved回調函數
.finally(() => {···}); //在執行`then`或`catch`後,都會執行`finally`回調

2、Promise.prototype.then()

第一個參數是resolved狀態的回調函數,
第二個參數(可選)是rejected狀態的回調函數json

getJSON("/post/1.json").then(
  post => getJSON(post.commentURL)
).then(
  comments => console.log("resolved: ", comments),
  err => console.log("rejected: ", err)
);

第一個`then`方法指定的回調函數,返回的是另外一個`Promise`對象。
第二個`then`方法指定的回調函數,就會等待這個新的`Promise`對象狀態發生變化。若是變爲`resolved`,就調用第一個回調函數,
若是狀態變爲`rejected`,就調用第二個回調函數。

3、Promise.prototype.catch()

Promise.prototype.catch() 是.then(null, rejection)或.then(undefined, rejection)的別名。數組

和then的二個參數同樣用來指定reject的回調
可是比then的二個參數一個做用:在執行resolve的回調(也就是上面then中的第一個參數)時,若是拋出異常了(代碼出錯了),那麼並不會報錯卡死js,而是會進到這個catch方法中
基本寫法
// 寫法一
const promise = new Promise(function(resolve, reject) {
  try {
    throw new Error('test');
  } catch(e) {
    reject(e);
  }
});
promise.catch(function(error) {
  console.log(error);
});

// 寫法二
const promise = new Promise(function(resolve, reject) {
  reject(new Error('test'));
});
promise.catch(function(error) {
  console.log(error);
});

then的第二個函數與catch( )的區分

(1)Promise內部報錯 則then的第二個函數和catch就近原則能捕獲到promise

const promise = new Promise((resolve, rejected) => {
    throw new Error('test');
});

//狀況一:既有第二個函數也有catch時 就近原則
promise.then(res => {
}, err => {
    console.log('我比較近我能捕獲到',err);
}).catch(err1 => {
    console.log(err1);
});
運行結果:我比較近我能捕獲到,test

//狀況二:只有第二個函數或只有catch 那就是它能捕獲

(2) then的第二個的函數捕獲不了then中的第一個函數拋出的錯誤,然後續的.catch能夠捕獲。服務器

Promise.resolve()
  .then(function success (res) {
    throw new Error('error')
  }, function fail1 (e) {
    console.error('fail1: ', e)~~~~
  })
  .catch(function fail2 (e) {
    console.error('fail2: ', e)
  })

運行結果:
fail2: Error: error
    at success (...)
    at ...

4、Promise.prototype.finally()

如服務器使用 Promise 處理請求,而後使用finally方法關掉服務器app

server.listen(port)
  .then(result => {···})
  .finally(server.stop);

5、Promise的一些方法

Promise.all() 全返回回來纔回調操做

// 生成一個Promise對象的數組
const promises = [2, 3, 5, 7, 11, 13].map(function (id) {
  return getJSON('/post/' + id + ".json");
});

Promise.all(promises).then(function (posts) {
}).catch(function(reason){
});

若是子promise沒有報錯了 可是子promise沒有定義catch, 就會調用promise.all的catch。異步

Promise.race() 只要有一個回來就回調操做

// 有一個圖片加載完就添加到頁面
  function loadImg(src){
    return new Promise((resolve,reject)=>{
      let img=document.createElement('img');
      img.src=src;
      img.onload=function(){
        resolve(img);
      }
      img.onerror=function(err){
        reject(err);
      }
    })
  }

  function showImgs(img){
    let p=document.createElement('p');
    p.appendChild(img);
    document.body.appendChild(p)
  }

  Promise.race([
    loadImg('http://www.baidu.com/1.png'),
    loadImg('http://www.baidu.com/567751/2.png'),
    loadImg('http://www.baidu.com/567751/3.png')
  ]).then(showImgs)

Promise.resolve( ) 轉爲Promise對象

(1)參數是一個 Promise 實例 原封不動地返回這個實例
(2)不帶有任何參數 直接返回一個resolved狀態的 Promise 對象
(3)參數是一個thenable對象(即具備then方法的對象)
Promise.resolve方法會將這個對象轉爲 Promise 對象,而後就當即執行thenable對象的then方法。

//`thenable`對象指的是具備`then`方法的對象
let thenable = {
  then: function(resolve, reject) {
    resolve(42);
  }
};

let p1 = Promise.resolve(thenable);
p1.then(function(value) {
  console.log(value);  // 42
});

(4)參數不是具備then方法的對象,或根本就不是對象
若是參數是一個原始值,或者是一個不具備then方法的對象,則Promise.resolve方法返回一個新的 Promise 對象,狀態爲resolved

const p = Promise.resolve('Hello');

p.then(function (s){
  console.log(s)
});
// Hello

Promise.reject( ) 轉爲Promise對象 且狀態是rejected

和Promise.resolve方法同樣,Promise.reject方法產生的Promise對象的狀態是rejected的。

const p = Promise.reject('出錯了');
// 等同於
const p = new Promise((resolve, reject) => reject('出錯了'))

p.then(null, function (s) {
  console.log(s)
});
// 出錯了

mark一下 僅供參考 歡迎更正補充 Thanks


參考資料:
阮一峯:https://es6.ruanyifeng.com/?search=String.raw&x=0&y=0#docs/promise#Promise-all
關於promise的十道題目:https://juejin.im/post/5a0406...
性感的Promise,擁抱ta而後扒光ta:https://juejin.im/post/5ab20c...
通俗易懂的Promise:https://juejin.im/post/5afe6d...

相關文章
相關標籤/搜索