Promise的作用

Promise是一个对象,代表一个异步操作是成功还是失败。Promise的作用:

1、同时处理多个并发请求操作。

2、链式调用用来解决回调地狱问题。

(注:回调地狱,即回调函数中调用的函数依赖回调函数运行的结果,多个这样的回调函数构成回调地狱。)

Promise的使用

Promise的约定:

  • 在本轮事件循环运行完成之前,回调函数不会执行。
  • 通过then()添加的回调函数一定会被执行。
  • 通过多次调用then(),可以添加多个回调函数。

Promise的用法:

一般链式写法

new Promise((resovle, reject)=>{
    resovle()
}).then((resovle, reject) => {
   resovle() // reject()
})
.then((newResult)=> {
  return doThirdThing(newResult); //返回结果
})
.then((finalResult)=> {
  console.log('Got the final result: ' + finalResult);
})
.catch(failureCallback);

组合用法

同时执行多个异步:Promise.all([])、Promise.race([])

Promise.all([]):最慢的异步操作执行完,再去调用回调。

Promise.race([]):最快的异步操作执行完,就去调用回调。

手动创建一个成功或失败的Promise: Promise.resolve()/Promise.reject()

Promise中的错误处理

catch捕获错误,只捕获当前链上的错误,不包含嵌套promise链上的错误。

例子1:

new Promise((resolve, reject) => {
    console.log('初始化');
    resolve();
})
.then(() => {
    throw new Error('有哪里不对了');
    console.log('执行「这个」”');
})
.catch(() => {
    console.log('执行「那个」');
})
.then(() => {
    console.log('执行「这个」,无论前面发生了什么');
});

//初始化
//有哪里不对了
//执行「那个」
//执行「这个」,无论前面发生了什么

例子2: 包含一个嵌套promise链,就算这个嵌套链上没有catch,这个嵌套链上的报的错,最外面的promise链上的catch也不能捕获到。

new Promise((resolve, reject) => {
    console.log('初始化');
    resolve();
})
.then(() => {
    new Promise((resolve, reject) => {
        console.log('「嵌套」');
        resolve();
    }).then(()=> {
        throw new Error('有哪里不对了');
    }).catch(()=> {
        console.log('执行「嵌套」');
    })
        console.log('执行「这个」');
})
.catch(() => {
    console.log('执行「那个」');
})
.then(() => {
    console.log('执行「这个」,无论前面发生了什么');
});

//初始化
//「嵌套」
//有哪里不对了
//执行「这个」
//执行「这个」,无论前面发生了什么

注意点:

  • then() 返回一个promise对象
  • then()中的参数可选,catch(failureCallback)等同于then(null, failureCallback)
  • then()中return返回Promise链
  • 最后通过catch终止Promise链
  • catch只捕获当前链上的错误,不包括其嵌套promise链上的错误

Promise的应用场景举例

合适的使用Promise可以编写更具可复用性和可维护性的代码。

案例1:

封装一个等待1000毫米的函数


function sleep(time) {
    return new Promise((r, j) => {
        setTimeout(() => {
            r()
        }, time);
    })
}

sleep(1000).then(success => {
    console.log('success')
}).catch(err => {

})

最常见的应用场景是封装一个ajax请求

// 简略实现ajax
function ajax(url,type){
    return new Promise((resolve,reject) => {
        var XHR = new XHRHttpRequest();
        XHR.open(type,url,true);
        XHR.send();
        XHR.onreadystatechange = () => {
            if(XHR.readyState == 4) {
                if(XHR.status == 200) {
                    try {
                        let response = JSON.parse(XHR.responseText);
                        resolve(response);
                    } catch(e) {
                        reject(e);
                    }
                } else {
                    reject(new Error(XHR.statusText));
                }
            }
        }
    });
}

案例2:

图片请求超时提醒

    function requestImg(){
        var p = new Promise((resolve, reject) => {
            var img = new Image();
            img.onload = function(){
                resolve(img);
            }
            img.src = '图片的路径';
        });
        return p;
    }
    //延时函数,用于给请求计时
    function timeout(){
        var p = new Promise((resolve, reject) => {
            setTimeout(() => {
                reject('图片请求超时');
            }, 5000);
        });
        return p;
    }
    Promise.race([requestImg(), timeout()]).then((data) =>{
        console.log(data);
    }).catch((err) => {
        console.log(err);
    });

参考资料:

MDN: promise

promise讲解1

promise讲解2


贝er
58 声望6 粉丝

不仅仅是程序员