JS问题整理与思考--Promise的基本使用和原理

用链式then操作时,前面的then要返回img,否则后面的then中img时undifined

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.src = src
    })
    return promise
}

var src = 'http://mazhaoyang.cn/Public/Blog/src/images/logo2.png';
var result = loadImg(src)
result.then(function (img) {
    console.log(1,img.width)
    return img
},function () {
    console.log(222)
}).then(function (img) {
    console.log(img);
    console.log(1,img.height)
},function () {
    console.log(333)
})

异常捕获

.then可以只操作一个函数,catch统一调用

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.src = src
    })
    return promise
}
var src = 'http://mazhaoyang.cn/Public/Blog/src/images/logo2222.png';
var result = loadImg(src)
result.then(function (img) {
    console.log(1,img.width)
    return img
}).then(function (img) {
    console.log(1,img.height)
}).catch(function (ex) {
    // 统一处理异常
    console.log(ex)
})

多个串联

第一个.then后面返回result2,那么第二个.then 监听的就是第二个图片的成功回调,达到串联的效果

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.src = src
    })
    return promise
}
var src1 = 'http://mazhaoyang.cn/Public/Blog/src/images/logo2.png';
var result1 = loadImg(src1)
var src2 = 'http://mazhaoyang.cn/Public/Blog/src/images/backToTop.png';
var result2 = loadImg(src2)

result1.then(function (img1) {
    console.log('第一个图片加载完成', img1.width)
    return result2
}).then(function (img2) {
    console.log('第二个图片加载完成', img2.width)
}).catch(function (ex) {
    console.log(ex);
})

Promise.all & Promise.race

  • Promise.all:所有Promise全部完成,统一执行success
  • Promise.race:只要有一个完成,就执行success
// Promise.all 接收一个promise对象数组
// 待全部完成之后,统一执行success
Promise.all([result1,result2]).then(datas =>{
    // 接收到的datas是一个数组,依次包含多个promise
    console.log(datas[0])
    console.log(datas[1])
})

//Promise.race 接收一个包含多个promise对象的数组
// 只要有一个完成,就执行success
Promise.race([result1,result2]).then(data=>{
    // data 即最先执行完成的promsie的返回值
    console.log(data)
})
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.src = src
    })
    return promise
}
var src1 = 'http://mazhaoyang.cn/Public/Blog/src/images/logo2.png';
var result1 = loadImg(src1)
var src2 = 'http://mazhaoyang.cn/Public/Blog/src/images/backToTop.png';
var result2 = loadImg(src2)

Promise.all([result1,result2]).then(function (datas) {
    console.log('all',datas[0])
    console.log('all',datas[1])
})
Promise.race([result1,result2]).then(function (data) {
    console.log('race',data)
})

随机浏览