Promise 基礎用法

Wang豔芬發表於2018-03-24

Promise ,為什麼會出現它,Promise 的出現,解決了哪些問題呢?

  • 解決了回撥地獄(巢狀)的問題,不會導致難以維護。
  • 解決同步&非同步的返回結果,並且按照順序返回

大家應該都知道,在 JavaScript 的世界裡,所有程式碼的執行都是單執行緒操作的。由於這個問題,導致 JavaScript 所有請求操作都必須非同步執行。

Promise 本意是承諾,在程式中的意思就是承諾我過一段時間後給你返回一個結果。什麼時候會用到(多一段時間)?那就是(非同步操作),非同步是指過了很長時間後才會返回結果。比如 網路請求、讀取本地檔案等~

基本用法

首先,我們去控制檯列印一下 Promise,如圖

image.png
很直觀的看出來,Promise 是一個建構函式

  • Promise 物件擁有兩種例項方法(prototype):then() 和 catch() 。
  • Promise 還擁有四個靜態方法,分別是:all、race、reject、resolve。

我們粘一段程式碼,小白如何呼叫 Promise

// 引入 Promise 模組
let Promise = require('promise')
let p = new Promise(function(resolve, reject){
    // 如果同時呼叫成功和失敗的方法,那麼執行順序就是:誰在前,就調誰。
    reject(100);
    resolve(1);
})
// then 接受兩個回撥函式,一個是成功的回撥,一個是失敗的回撥
p.then(function(data){
    console.log('data', data)
},function(err){
    console.log('err', err)
})
// 控制檯列印的結果為:data 100
複製程式碼

接下來我們來看看 Promise 有哪些 API

then() 方法

從例子中可以看出 then 方法可以接收兩個引數,且通常都是函式。第一個引數是成功的回撥,第二個引數是失敗的回撥。這兩個引數都會將回撥存放在對應的陣列內,當 promise 狀態改變之後,呼叫成功或者失敗的陣列即可

  • then 方法可以鏈式呼叫,與 jquery 不同,jquery 的鏈式呼叫靠的是返回的 this,可惜的是, promise 不能返回 this,promise 實現鏈式呼叫靠的是返回一個新的 Promise
let p = new Promise(function(resolve, reject){
    resolve()
})
// p2 和 p 不是一個東西,如果是,就會走成功了。就不會走失敗了
let p2 = p.then(function(){
    throw new Error('錯誤')
})
p2.then(function(data){
    console.log(data)
},function(err){
    console.log(err)
})
// 控制檯列印結果:Error: 錯誤
複製程式碼
  • promise 例項可以多次 then,當成功後,會將 then 中的成功方法按順序執行
let p = new Promise(function(resolve, reject){
    // 定時器來非同步回撥
    setTimeout(function(){
        resolve(1000)
    }, 1000)
})
p.then(function(data){
    console.log('data', data)
},function(err){
    console.log('err', err)
})
p.then(function(data){
    console.log('data', data)
},function(err){
    console.log('err', err)
})
// 列印結果:
data 1000
data 1000
複製程式碼

catch() 方法

它有兩個作用:
  • 可以和 then 的第二個引數一樣,用來指定 reject 的回撥
  • 執行 then 第一個回撥引數時,如果丟擲異常,會直接走 catch 方法
let p = new Promise(function(resolve, reject){
    reject(new Error('error'))
})
// then 沒有寫第二個 reject 回撥
p.then(function(data){
    console.log(data)
}).catch(function(reasone){
    console.log(reasone)
})
// 列印結果: Error: error
複製程式碼

resolve() & reject() 方法

  • Promise.resolve() 相當於建立了一個立即 resolve 物件,使得 promise 物件直接 resolve。
Promise.resolve(5).then(function(data){
    console.log(data)
})
// 列印結果:5
複製程式碼
  • Promise.reject() 相當於建立了一個立即 reject 物件,使得 promise 物件直接 reject,並把 error 傳到 catch 函式中
Promise.reject(new Error('error')).catch(function(err){
    console.log(err)
})
// 列印結果:Error: error
複製程式碼

all() 方法

  • Promise.all() 接收的引數是 promise 物件組成的陣列,並返回新的 promise 物件。
Promise.all([Promise.resolve(100),Promise.resolve(200)]).then(function(data){
    console.log('成功:',data)
},function(err){
    console.log(err)
})
// 列印結果:成功: [ 100, 200 ]
複製程式碼
  • 當陣列中有一個 reject 時,會改變狀態,並執行錯誤狀態
Promise.all([Promise.resolve(100),Promise.reject(new Error('error'))]).then(function(data){
    console.log('成功:',data)
},function(err){
    console.log(err)
})
// 列印結果:Error: error
複製程式碼

race() 方法

  • Promise.race() 同樣接收的引數是 promise 物件組成的陣列,並返回新的 promise 物件。與 Promise.all() 不同的是隻要第一個陣列成功了。就算成功。如果第一個失敗了。就算失敗
// 成功的狀態,第一個陣列物件,成功了就不會執行下一個陣列物件
Promise.race([Promise.resolve(100),Promise.reject(new Error('error'))]).then(function(data){
    console.log('成功:',data)
},function(err){
    console.log(err)
})

// 失敗的狀態,第一個陣列物件失敗,就會報錯,後面也不執行
Promise.race([Promise.reject(new Error('error')),Promise.resolve(100),Promise.reject(new Error('error'))]).then(function(data){
    console.log('成功:',data)
},function(err){
    console.log(err)
})
複製程式碼

友情連結

相關文章