ES6 Peomise詳解

 如果你看了我的上一篇文章,也就是 jQuery.Deferred 那麼這篇文章應該很好理解

點擊查看~

/** 
 *  Promise
 * 這是一個簡單的 promise
 * new Promise : 定義了一個 promise 對象 
 * resolve : 這是定義成功執行的回調函數
 * reject : 這是定義失敗執行的回調函數
 * then : 傳入兩個函數, 一個是成功時候調用的函數, 一個是失敗的時候調用的函數
 *        返回的必須是一個 Promise 實例, then 返回的默認就是 執行 then 函數的對象, 纔可以鏈式操作
 */

var ajax = () => {
    console.log('1')
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve()
        }, 1000)
    })
}

ajax()
    .then(() => {
        return new Promise((resolve, reject) => {
            console.log('2')
            setTimeout(() => {

                resolve()
            }, 2000)
        })
    })
    .then(() => {
        console.log('3')
    })


/** 
 * promise 小 demo 打印圖片的寬高
 */
function loadImg(src) {
    var promise = new Promise(function(resolve, reject) {
        var img = document.createElement('img')
        img.onload = function() {
            resolve(img)
        }
        img.onerror = function() {
            reject(img)
        }
        img.src = src
    })
}
var src = "//www.baidu.com/img/bd_logo1.png?where=super"
var result = loadImg(src)
result.then(function(img) {
    console.log("width", img.width);
    // return img 不然的話 會報錯 錯誤是 height undefined .
    // 爲什麼是這樣是因爲 : 函數需要有返回值的啊.
    return img
}, function(img) {
    console.log("err 1");
}).then(function(img) {
    console.log("height", img.height);
}, function(img) {
    console.log("err 2");
})





// 定義一個 promise 函數,
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) {
    img.forEach(item => {
        document.body.appendChild(item)
    });
}
// /** 
//  * all : 是當所有的都加載過之後纔會執行.
//  */
Promise.all([
    loadImg(
        '//www.baidu.com/img/bd_logo1.png?where=super'
    ),
    loadImg(
        '//www.baidu.com/img/bd_logo1.png?where=super'
    ),
    loadImg(
        '//www.baidu.com/img/bd_logo1.png?where=super'
    )
]).then(showImgs)



/** 
 * 捕獲成功時的異常 
 */

function loadImg(src) {
    return new Promise(function(resolve, reject) {
        var img = document.createElement('img')
        img.onload = function() {
            resolve(img)
        }
        img.onerror = function() {
            reject(err)
        }
        img.src = src
    })
}
var src = "//www.baidu.com/img/bd_logo1.png?where=super"
var result = loadImg(src)

result.then(function(img) {
    console.log("width", img.width);
    throw new Error('自定義錯誤') // 模擬異常.
    return img
}).then(function(img) {
    console.log("height", img.height);
}).catch(function(ex) { // 相當於 try...catch
    console.log(ex);
})


/**
 * 捕獲失敗時的異常
 */
function loadImg(src) {
    return new Promise(function(resolve, reject) {
        var img = document.createElement('img')
        img.onload = function() {
            resolve(img)
        }
        img.onerror = function() {
            reject("圖片加載失敗")
        }
        img.src = src
    })
}
// 手動把圖片的地址改爲異常,所以就會捕獲到異常
var src = "//1www.baidu.com/img/bd_logo1.png?where=super"
var result = loadImg(src)

result.then(function(img) {
    console.log("width", img.width);
    return img
}).then(function(img) {
    console.log("height", img.height);
}).catch(function(ex) {
    console.log(ex); // 打印異常
})


/**
 * promise 串聯
 */
function loadImg(src) {
    return new Promise(function(resolve, reject) {
        var img = document.createElement('img')
        img.onload = function() {
            resolve(img)
        }
        img.onerror = function() {
            reject("圖片加載失敗")
        }
        img.src = src
    })
}
var src1 = "//www.baidu.com/img/bd_logo1.png?where=super"
var result1 = loadImg(src1)
var src2 = 'https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=1299248511,111772763&fm=26&gp=0.jpg'
var result2 = loadImg(src2)

result1.then(function(img) {
    console.log('第一個圖片加載成功', img.width);
    // 一定要 return 下一個 的對象 ,不然執行的還是 result1 的then
    return result2
}).then(function(img) {
    console.log('第二個圖片加載成功', img.width);
}).catch(function() {
    console.log('加載失敗');
})


/** 
 * Promise.all  和 Promise.race
 * all : 等到所有的 promise 都執行過才執行
 * race : 只要有其中一個 promise 執行後就執行
 */

function loadImg(src) {
    return new Promise(function(resolve, reject) {
        var img = document.createElement('img')
        img.onload = function() {
            resolve(img)
        }
        img.onerror = function() {
            reject("圖片加載失敗")
        }
        img.src = src
    })
}
var src1 = "//www.baidu.com/img/bd_logo1.png?where=super"
var result1 = loadImg(src1)
var src2 = 'https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=1299248511,111772763&fm=26&gp=0.jpg'
var result2 = loadImg(src2)
Promise.all([result1, result2]).then(function(datas) {
    console.log(datas[0]);
    console.log(datas[1]);
})
Promise.race([result1, result2]).then(function(data) {
    console.log('race', data);
})

/** 
 * 總結: promise 是一個構造函數
 * 狀態 : promise 有三個狀態 剛開始的時候時 待執行狀態, 執行成功時的狀態, 執行失敗時的狀態
 * 接受兩個參數 : resolve reject 
 *               resolve : 定義執行成功時的回調函數
 *               reject : 定義執行失敗時的回調函數
 * then : 傳入兩個函數, 一個是成功時候調用的函數, 一個是失敗的時候調用的函數
 *        返回的必須是一個 Promise 實例, then 返回的默認就是 執行 then 函數的對象, 纔可以鏈式操作
 * 捕獲異常 : Error 和 reject 都要考慮
 * catch : 統一捕獲異常,只需要再最後一個 then 的後面加上 catch 函數.
 *       : 這個就相當於 我們 try...catch 時一樣的.
 * Promise.all : 用一個數組, 傳入多個 promise ,等到所有的 promise 實例都加載完成之後, 再執行
 * Promise.race : 用一個數組, 傳入多個 promise, 只要有一個 promise 實例加載完成之後, 就執行.
 * 多個串聯 : 再上一個then 函數結尾的時候 return 下一個 promise 對象, 就可以達到串聯
 */

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章