Promise简介

289 阅读3分钟
  1. 什么是Promise

    Promise是JS异步编程的一种解决方案,是传统回调方式的一种进化版本。它最早由社区提出和实现,ES6将其写进了语言标准,提供了原生Promise。

    Promise 翻译汉语为“承诺”,承诺在未来某个时刻把异步操作的结果--成功(resolved)或者失败(rejected)交付给你。这样就可以把异步方法可以像同步方法那样返回值,但并不是立即返回结果,而是在未来会把结果返回给你。

    Promise可以理解为一个状态机,它有三种状态:pending(进行中),fulfilled(已完成),和rejected(已失败),而且状态一旦改变后,不能再被改变。从JS语言的角度出发,Promise是一个对象,可以认为是一个构造函数。

  2. Promise的使用

  • 把传统的回调方式promiseify,然后可以链式调用
const http=require('http');

function GET(url) {
    return new Promise((resolve, reject) => {
        const req = http.get(url, (res) => {
            const { statusCode } = res;
            let error;
            if (statusCode !== 200) {
                reject('Request Failed.\n' + `Status Code: ${statusCode}`);
                return;
            }

            let rawData = '';
            res.on('data', (chunk) => { rawData += chunk; });
            res.on('end', () => {
                resolve(rawData);
            });
        });

        req.on('error', (e) => {
            reject(`Got error: ${e.message}`);
        });
    });

}

GET('https://www.baidu.com').then(re=>{
    console.log('请求返回结果:',re);
});

  • Promie.all和Promise.race

如果我们同时需要多次请求,而且请求之间不相互依赖,这时我们可以使用Promise.all并发的请求,来提高性能:

const p1 = GET('https://www.baidu.com');
const p2 = GET('https://www.qq.com/');
Promise.all([p1, p2]).then(([res1, res2]) => {
    console.log('百度返回结果:', res1);
    console.log('QQ返回结果:', res2);
});

Promise.race和Promise.all类似,但是它只返回处理最快的结果:


const p4 = new Promise((resolve, reject) => {
    setTimeout(resolve, 500, 'one');
});
const p5 = new Promise((resolve, reject) => {
    setTimeout(resolve, 100, 'two');
});

Promise.race([p4, p5]).then(re => {
    console.log(re);
});
  • promise 和async、await 结合,让写异步和同步得到同样的体验,简直爽到家 这里我们改写一下Promise.all的例子,不采用链式调用的形式
async function task() {
    const p1 = GET('https://www.baidu.com');
    const p2 = GET('https://www.qq.com/');
    const [res1, res2] = await Promise.all([p1, p2]);
    console.log('百度返回结果:', res1);
    console.log('QQ返回结果:', res2);
}

task();

上面写的方式没有回调,也没有链式调用,异步的api,但是和写同步的代码一样,非常整洁。Promise和async ,await函数的结合,个人感觉一下把JS这门语言提高了一个档次。

  • promise.catch 异常的捕获 在执行的过程中,promise封装的异步操作发生异常怎么处理呢,一般我们会采用三种方式来处理。
// 第一种
GET('https://www.baidu.com')
    .then(function success(res) {
        console.log(res);
    }, function fail(e) {
        console.error('fail: ', e)
    });
// 第二种
GET('https://www.baidu.com')
    .then(function success(res) {
        console.log(res);
    }).catch(function fail(e) {
        console.error('fail: ', e)
    });

// 第三种在函数中,通过try {}catch(){}
async function task() {
    try {
        const p1 = GET('https://www.baidu.com');
        const p2 = GET('https://www.qq.com/');
        const [res1, res2] = await Promise.all([p1, p2]);
        console.log('百度返回结果:', res1);
        console.log('QQ返回结果:', res2);
    } catch (err) {
        console.log(err);
    }
}

前两种方式基本上是一样的,第二种可以理解为第一种的简洁形式。

结语

Promise的简介就写到这里,这里的内容是平常最常用的。后面会写一些关于Promise的例子,来提升对Promise的理解。