Promise筆記

定義:用於異步計算
可以將異步操作隊列化
可以在對象之間傳遞和操作Promise,幫助我們處理隊列

二.回調有四個問題
1.嵌套層次很深,難以維護
2.無法正常使用return 和 throw
3.難以在多個回調之間
4.無法正常檢索堆棧信息

三.promise基本寫法

   new Promise(
       /* 執行器 executor */
        function (resolve, reject){
            // 一段耗時很長的異步操作
            resolve();// 數據處理完成
            reject();//數據處理出錯
        })
        .then(function A(){
            //成功,下一步
        }, function B() {
            //失敗,做相應處理
        })

四.promise嵌套

new Promise( resolve => { 
    setTimeout( () => {
        resolve('hello');
    }, 2000);
})
.then( value => {
    console.log(value);
    return new Promise(resolve=> {
        setTimeout( () => {
            resolve('world');
        }, 2000)
    })
})
.then( value => {
    console.log(value + 'world')
})

五.錯誤處理
1.reject(‘error’).then(null,message => {})
2.throw new Error(‘error’).catch(message => {})
推薦使用第二種,更加清晰好讀,並且可以捕獲前面(then方法)的錯誤

new Promise( resolve => {
    setTimeout( () => {
        throw new Error('bye');
    }, 2000)
})
.then( value => {
    console.log(value + ' world');
})
.catch( error => {
    console.log( 'Error: ', error.message);
})
new Promise( (resolve, reject) => {
    setTimeout( () => {
        reject('bye');
    }, 2000)
})
.then( value => {
    console.log(value + ' world');
}, value=> {
    console.log( 'Error: ', value);
})

Promise.all()

最常見的就是和.map() 連用

new Promise( (resolve, reject) => {
    let p1 = new Promise(resolve => {
        setTimeout( () => {
            resolve('I am P1');
        }, 1000)
    })
    let p2 = new Promise(resolve => {
        setTimeout( () => {
            resolve('I am P2');
        }, 2000)
    })
    return Promise.all([p1, p2])
})
.then( all => {
    console.log(all + ' all');
})
.catch( error => {
    console.log( 'Error: ', error.message);
})

實現隊列

function queue(things) {
    let promise = Promise.resolve();
    things.forEach( thing => {
        promise = promise.then( () => {
            return new Promise( resolve => {
                doThing(thing, () => {
                    resolve();
                })
            })
        })
    })
    return promise;
}
queue(['lots','of','things',...])

promise.race()
常見用法:
把異步操作和定時器放在一起
如果定時器先觸發,就認爲超時,告知用戶‘網絡超時’

實戰1
把任何異步操作包裝包Promise
假設需求:
用戶點擊按鈕,彈出確認窗體
用戶確認和取消有不同的處理

let confirm = popupManager.confirm('您確定麼');
confirm.promise
    .then( () => {
        //do confirm staff
    })
    .catch( () => {
        //do cancel staff
    })
//窗體的構造函數
class Confirm {
    constructor() {
        this.promise = new Promise( (resolve, reject) => {
            this.confirmButton.onclick = resolve;
            this.cancelButton.onClick = reject;
        })
    }
}

jQuery已經實現了Promise
IE不支持promise

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