Promise 讓你的專案更有逼格

劉清朗發表於2018-08-13

Promise 讓你的專案更有逼格

promise 詳解

概念:Promise是非同步程式設計的一種解決方案,比傳統的解決方案——回撥函式和事件——更合理和更強大。所謂Promise,簡單說就是一個容器,裡面儲存著某個未來才會結束的事件(通常是一個非同步操作)的結果。
直接看各種demo 拗口的文字直接丟棄掉,選擇遺忘吧

promise 出現的原因

let cb = (data) => {
    console.log(data)
}

let ajax = (cb) => {
    console.log('ajax ---- ')
    if (typeof cb == 'function') {
        cb('callback ----')
    }
}
ajax(cb)
/**
 * console.log
 * ajax ----
 * callback ----
 */
複製程式碼
1.缺點一直需要cb傳遞,如果掛在全域性物件,則會操作汙染
2.程式碼易讀性比較差
3.特別需要獲取多個非同步操作時,無法很好檢測結果完成

舉例子說明上述第三點

let num = 1;
let ajax1 = () => {
    setTimeout(() => {
        num++;
        console.log(1000);
        callbackAll();
    }, 1000)
}
let ajax2 = () => {
    setTimeout(() => {
        num++;
        console.log(1500)
        callbackAll();
    }, 1500)
}
let ajax3 = () => {
    setTimeout(() => {
        num++;
        console.log(2000)
        callbackAll();
    }, 2000)
}
let ajaxAll = () => {
    ajax1();
    ajax2();
    ajax3();
}
let callbackAll = () => {
    if (num == 3) {
        // 全部完成
        console.log('全部完成~')
    }
}

複製程式碼
如果用promise 方案解決 程式碼如下
let ajax1 = () => {
    return new Promise((reslove, reject) => {
        setTimeout(() => {
            console.log(1000);
        }, 1000)
    })
}
let ajax2 = () => {
    return new Promise((reslove, reject) => {
        setTimeout(() => {
            console.log(1500);
        }, 1500)
    })
}
let ajax3 = () => {
    return new Promise((reslove, reject) => {
        setTimeout(() => {
            console.log(2000);
        }, 2000)
    })
}

Promise.all([ajax1, ajax2, ajax3]).then(function() {
        console.log('全部完成~')
    }).catch(function(err) {

    })
/** 
 * 對比一下,會看到程式碼的整體的美觀度得到很大的提升
 * 
 */
複製程式碼
既然說到了promise all then catch 我們來分別講解一下
then 所有的promise例項 都有then 方法,來對這個promise例項 做下一步的處理,then 接受兩個方法,第一個對應resolve 第二個對應 reject
let person = () => {
    return new Promise(function(resolve, reject) {
            setTimeout(function() {
                resolve(10)
            }, 1000)
        })
        .then(function(data) {
            console.log(data)
        })
}

// data == 10

// 有時候會看到直接return 的資料
// promise 例項 被 resolved then方法的第一個回掉方法會被執行

複製程式碼
如果被 rejected,then方法的第二個回掉會被執行
let person = () => {
    return new Promise((resolve, reject) => {
            setTimeout(function() {
                reject(20)
            }, 1000)
        })
        .then(function(num) {
            console.log(num + 'suc')
        }, function(num) {
            console.log(num + 'err')
        })
}
複製程式碼
catch promise 例項 被rejected時,catch回撥函式被執行
可以參考下面的例子
new Promise((res, rej) => {
    setTimeout(function() {
        rej(11)
    }, 500)
}).then(function() {
    console.log('success')
}).catch((err) => {
    console.log('err')
})
複製程式碼

all 有許多個非同步任務被同時觸發,但你只想在它們都完成之後才做出迴應---這就是Promise.all的由來。Promise.all方法傳入一個promise的陣列,然後在它們全部resolved之後再出發回撥函式

Promise.all([promise1, promise1]).then(function(data) {
    // promise1 promise2 全部完成後 才會執行這裡
})
.catch(function(error) {
    // promise1 promise2 出現一個 rejected 時 執行這裡
});
複製程式碼
race不是等待所有的promise被resolved或者rejected,而是隻要陣列中有一個promise被resolved或者rejected,Promise.race方法就被觸發
var promise1 = new Promise(function(resolve, reject) {
    // A mock async action using setTimeout
    setTimeout(function() { resolve('1111!'); }, 8000);
});
var promise2 = new Promise(function(resolve, reject) {
    // A mock async action using setTimeout
    setTimeout(function() { resolve('2222!'); }, 3000);
});
Promise.race([promise1, promise2]).then(function(one) {
    console.log('執行結果: ', one);
}).catch(function(one, two) {
    console.log('報錯資訊: ', one);
});
複製程式碼

總結:

promise 結果回撥地獄的老問題,而且在串聯操作的方面then方法的使用使我們在處理業務邏輯時更好的去維護程式碼
promise 在前端中的使用越來越多,如果你不理解,確實缺少了一大利器

接下來 編寫自己的 promise 更深層次的理解promise 的原理

如果錯誤,請指出,感謝~

相關文章