1. 程式人生 > 程式設計 >淺析Promise的介紹及基本用法

淺析Promise的介紹及基本用法

Promise是ES6引入的非同步的新解決方案。語法止Promise是-一個建構函式,
用來封裝非同步操作並可以獲取其成功或失敗的結果。

  • Promise 建構函式: Promise (excutor) {}
  • Promise.prototype.then 方法
  • Promise.prototype.catch 方法

Promise的基本使用

例項化Promise

new Promise()

在例項化的時候接受一個引數, 這個引數是一個函式。

這個函式有兩個形參,resolve 和reject

var promise = new Promise((resolve,reject) => {
    // 裡面用於處理非同步操作
})

我們在這裡使用定時器來模擬非同步操作

promise有三種狀態,分別是:進行中、成功、失敗。

var promise = new Promise((resolve,reject) => {
    // 這是一個非同步操作
    setTimeout(() => {
        // 這裡模擬獲取資料
        var data = '獲取的資料'
        // 在得到資料之後我們可以呼叫resolve和reject方法來改變promise物件的狀態
        resolve(data)  // resolve可以將promise物件的狀態改為成功,reject()可以promise將物件狀態改為失敗
    },1000);
})

promise的then方法

當promise物件的狀態為成功或者失敗時可以呼叫then方法

then方法接受兩個引數,而且兩個引數都是函式型別的值

promise物件的狀態為成功時,會呼叫then方法的第一個引數

也是就說promise物件的狀態為失敗時,會呼叫then方法的第二個引數

第二個引數時可選的,如果不需要捕獲失敗可以省略

引數分別有一個形參,成功的函式叫value,失敗的err

promise.then(value => {
// 當非同步函式裡面呼叫了resolve(data),也是就說promise物件的狀態為成功時,會呼叫then方法的第一個引數
console.log(value);  // 'hello world' value就是resolve()方法傳遞過來的資料
},err => {
   // 當非同步函式裡面呼叫了reject(data),也是就說promise物件的狀態為失敗時,會呼叫then方法的第二個引數
    console.log(err);  // err就是reject()方法傳遞過來的資料 
})

呼叫then方法then方法的返回結果是Promise 物件,物件狀態由回撥函式的執行結果決定

如果回撥函式中返回的結果是非promise型別的屬性,狀態為成功,返回值為物件的成功的值

let data = promise.then((val) => {
    // console.log(val.result);
    // 返回非Promise的情況
    // return val.result
 
    // 返回Promise的情況
    return new Promise( (resolve,reject) => {
        // resolve('ok')
        reject('err')
    })
},err => {
console.log(err);
})
// 返回非Promise的情況 狀態為成功,返回值為物件的成功的值 
// 返回結果是Promise 物件,物件狀態由回撥函式的執行結果決定
// 丟擲錯誤,狀態為失敗
console.log(data);  

所以then可以鏈式呼叫使用方法可參見下面promise應用示例。

promise的catch方法

promise的catch方法是then(null,rejection)的別名,用於指定發生錯誤時的回撥

Promise物件的狀態為resMUgBpzYsolve,就會呼叫then方法的指定回撥函式

const promise = new Promise((resolve,reject) => {
    resolve('ok')
})
promise.then(val => {
    console.log(val);  // ok
}).catch(err => {
    console.log(err);
})

如果promise的狀態為rejected就會呼叫catch方法的回撥函式來處理這個問題。

const promise = new Promise((resolve,www.cppcns.com reject) => {
    reject('err')
})
promise.then(val => {
    console.log(val);
}).catch(err => {
    console.log(err);  // err
})

如果then方法在執行中出現錯誤也會被catch方法捕獲

const promise = new Promise((resolve,reject) => {
    resolve('err')
})
promise.then(val => {
    console.log('ok');    // ok
    throw '出錯了!!'     // then裡面丟擲的錯誤會繼續被catch捕獲
}).catch(err => {
    console.log(err);  // 出錯了!!
})

promise物件的錯誤具有冒泡的性質,會一直向後傳遞,直到被捕獲為止。也就是說,錯誤總是會被下一個catch捕獲。

const promise = new Promise((resolve,reject) => {
    resolve('ok')
})
promise.then(val => {
    return new Promise((resolve,reject) => {
        reject('err')
    })
})
.then(val => {
    return new Promise((resolve,reject) => {
        reject('err')
    })
})
.catch(err => {
    // 以上產生的錯誤都可以被catch捕獲到
    console.log(err);  // err
})

一般來說,不要在then方法中定義rejected狀態回撥函式(即then的第二個引數),而應總是使用catch方法。

promise應用

promise讀取檔案,多個檔案連續呼叫

在這個例子中我們用到了Node.的檔案模組

// 讀取檔案資訊
const fs = require('fs')

在下面程式碼中我們使用了promise包裝了非同步函式

我們先來看看正常的檔案讀取操作

// 讀取檔案資訊
const fs = require('fs')
 
// 如果讀取失敗err就是一個錯誤物件,讀取成功data就是資料
fs.readFile('./01.txt',(err,data) => {
    // 判斷是否出現錯誤,如果讀取錯誤就列印錯誤物件。
    if (err) {
        console.log(err);
        return
    }
    console.log(data.toString());
})

我們如果想在讀取成功之後繼續讀取檔案,就需要在回撥函式中繼續使用fs.readFile...去讀取檔案,巢狀層次一多,這樣一來就會形成回撥地獄。

接下來我們使用Promise的方式來讀取檔案

// 讀取檔案資訊
const fs = require('fs')
 
const promise = new Promise((resolve,reject) => {
    fs.readFile('./01.txt',data) => {
        if (err) return reject(err)
        resolve(data)
    })
})
 
promise.then(val => {
    console.log(val.toString());
    // 返回一個Promise物件
    return new Promise((resolve,reject) => {
        fs.readFile('./02.txt',data) => {
            if (err) return reject(err)
            resolve(data)
        })
    })
},err => {
    console.log(err);
})
// 上一個then裡面返回的是一個promise物件,我們可以繼續.then
.then(val => {
    console.log(val.toString());
    return new Promise((resolve,reject) => {
        fs.readFile('./03.txt',err => {
    console.log(err);
})
.then(val => {
    console.log(val.toString());
},err => {
    console.lwww.cppcns.comog(err);
})

promise封裝ajax請求

封裝了ajax請求,使用then獲取結果,讓程式碼看起來更加簡潔,解決了回撥地獄的問題

const promise = new Promise((resolve,reject) => {
    // 建立物件
    const x程式設計客棧hr = new XMLHttpRequest()
    // 初始化
    xhr.open("GET",'https://api.apiopen.top/getSongPoetry?page=1&count=20')
    // 傳送
    xhr.send()
    // 繫結事件處理響應結果
    xhr.onreadystatechange = function () {
        // 判斷
        // 進入最後一個階段,所有的響應體都回來了
        if (xhr.readyState === 4) {
            // 判斷響應碼
            if (xhr.status >= 200 && xhr.status < 300) {
                // 表示成功
                // console.log(JSON.parse(xhr.response));
                resolve(JSON.parse(xhr.response))
            } else {
                reject(xhr.status)
            }
        }
    }
})
// 指定回撥
promise.then((val) => {
    console.log(val);
},err => {
    console.log(err);
})

到此這篇關於淺析Promise的介紹及基本用法的文章就介紹到這了,更多相關Promise使用內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!