1. 程式人生 > >異步編程之promise

異步編程之promise

參數 完成 () child reac lld on() 立即執行 cat

是ES6中新增的異步編程解決方案。

1.構造函數。

可以通過promise構造函數來實例化。

數據:

const imgs = [
    ‘https://img.alicdn.com/tps/i4/TB1fD77gfuSBuNkHFqDSutfhVXa.jpg_240x240q90.jpg‘,
    ‘https://img.alicdn.com/simba/img/TB1CYyRdAUmBKNjSZFOSuub2XXa.jpg‘,
    ‘https://img.alicdn.com/imgextra/i3/31/TB2Yxd3gsuYBuNkSmRyXXcA3pXa_!!31-0-lubanu.jpg_200x200q90.jpg‘
]

實例化Promise對象接收一個參數是回調函數,這個函數又有兩個參數,分別是resolve和reject。

resolve異步操作執行成功的回調函數。reject異步操作執行失敗的回調函數。

const p = new Promise(function(resolve, reject) {
    const img = new Image();
    img.src = imgs[0];
    img.onload = function() {
        resolve(this);
    };
    img.onerror = function(err) {
        reject(err);
    }
});

Promise對象有三種狀態:狀態完全由異步操作的結果來決定。狀態一旦改變之後就不會再改變。

pending(進行中)===>Resolved(已完成)

pending(進行中)===>Rejected(已失敗)

這就創建了promise對象了,但是並沒有任何效果。這時就需要用到promise原型上的方法:Promise.prototype.then(), Promise.prototype.catch (),用來處理異步操作結果。處理成功和捕獲異常。

2.兩個原型方法。Promise.prototype.then(), Promise.prototype.catch ()

const p = new Promise(function(resolve, reject) {
    const img = new Image();
    img.src = ‘ ‘;
    img.onload = function() {
        resolve(this);
    };
    img.onerror = function() {
        reject(new Error(‘圖片加載失敗‘));
    }
});
p.then(function(img) {
    document.body.appendChild(img);
}).catch(function(err) {
    console.log(err);
})

3.兩個常用的靜態方法。Promise.all(), Promise.resolve()

3.1 promise.all()

可以將多個promise實例封裝成一個新的promise實例。使用的時候接受一個數組,這個數組就是多個promise組成的集合。除了接受數組,還可以接收具有itertor接口的對象。

當所有promise實例的狀態都變為resolved,promise.all的狀態才會變成resolved,此時返回值組成一個數組,傳遞給then中的resolve函數。只要有一個被rejected,promised.all的狀態就變成rejected,此時第一個被rejected的實例的返回值,會傳遞給p的回調函數。

function loadImg(url) {
    const p = new Promise(function(resolve, reject) {
        const img = new Image();
        img.src = url;
        img.onload = function() {
            resolve(this);
        };
        img.onerror = function() {
            reject(new Error(‘圖片加載失敗‘));
        }
    });
    return p;
}
const allDone = Promise.all([loadImg(imgs[0]), loadImg(imgs[1]), loadImg(imgs[2])]);
allDone.then(function(datas) {
    datas.forEach(function(item, i) {
        document.body.appendChild(item);
    })
}).catch(function(err) {
    console.log(err);
})

三張圖片全部在頁面顯示。如果換成:

const allDone = Promise.all([loadImg(imgs[0]), loadImg(imgs[1]), loadImg(imgs[2]), loadImg(‘ ‘)]);

一張都加載不出來,並且控制臺打印出錯信息。

技術分享圖片

3.2 Promise.resolve()

將一個對象轉換為promise對象。

用法1:接收一個promise實例,返回promise實例,不做任何修改。

Promise.resolve(loadImg(imgs[0])).then(function(img){
    document.body.appendChild(img);
})

用法2:將對象轉為promise對象,然後就立即執行thenable對象的then方法。

技術分享圖片

用法3:參數是一個基本數據類型或者不傳參數,那麽返回一個狀態為resolved即成功的promise對象。
Promise.resolve(‘perihe‘).then(function(str) {
    console.log(str); //perihe
})

不傳參:

const p = Promise.resolve()
console.log(p);

狀態為resolved的promised對象:

技術分享圖片

異步編程之promise