ES6规范的promise

本文探讨了JavaScript中的Promise,解释了其存在的意义,即解决异步操作的回调地狱问题。通过示例代码,展示了Promise的构造、状态变化以及then/catch方法的使用。还介绍了Promise.all和Promise.race的并行处理特性,帮助读者更好地理解和掌握Promise在实际开发中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

差不多一个月没写博客了,现在来开启新的一年第一篇博客。

今天来说说es6规范的promise属性,始终坚信,技术永无止境,无论做什么,都得从底层做起,基础很重要,一步一步,做大做强是吧,不废话了。

在技术领域,永远明白的一个真理,需求推动发展,都是为了更加方便,所谓存在即合理。

学习技术也有几个问题时刻问自己:这个东西是个啥?用来干啥?怎么用?

 promise存在的意义

在javascript的世界中,所有代码都是单线程执行的,由于这个“缺陷”,导致JavaScript的所有网络操作,浏览器事件,都必须是异步执行。异步执行可以用到回调函数,异步操作就是说在未来某个时间会触发某个操作,说到异步执行,脑子里马上浮现出ajax,看下面这一段代码:

request.onreadystatechange = function () {
    if (request.readyState === 4) {
        if (request.status === 200) {
            return success(request.responseText);
        } else {
            return fail(request.status);
        }
    }
}

 

可以看到,上面通过判断状态,来执行成功或者失败的操作。对于上面的判断等等操作,我们不好复用,有人说,可以传递失败或者成功的函数作为参数,想法很好。但是首先这样代码不好看,而且对于多个依赖请求,那么是无法实现的。我们都知道jquery其中一个很强大的东西就是链式调用,为什么可以,就是每次调用都返回一个jquery对象。正因为有需求,于是promise出现了, es6对其进行了规范。

揭开promise面纱

promise,英文意思为“承诺”,要理解一个函数,就去看他的英文意思,毕竟外国人搞得嘛。

promise是什么?很简单,javascript不是一切皆对象,promise也是javascript的一个特殊对象,通过构造函数Promise生成。

解决了什么问题?promise给出一个承诺,不管失败还是成功都会给出响应,看一段代码。

function randomNum(resolve, reject) {
    var timeOut = Math.random() * 2; // 生成0-2随机数
    console.log('set timeout to:' + timeOut + ' seconds');
    setTimeout(function () {
        if (timeOut < 1) {
            console.log('resolve...');
            resolve('200 OK');
        } else {
            console.log('reject...');
            reject('timeout in' + timeOut + ' seconds');
        }
    }, timeOut * 1000);
}

//执行
var p1 = new Promise(randomNum);
console.log(p1);
var p2 = p1.then(function (result) {
    console.log('成功:' + result);
});
var p3 = p1.catch(function (reason) {
    console.log('失败:' + reason);
});

明确上面几个东西:

resolve, reject是js引擎自带的函数,resolve表示成功执行的函数,reject表示失败执行的函数,我们通过一个定时器,来模拟网络的延迟效果。打印一下p1

由于随机数的关系,这时候走的是失败的情况。发现里面有个状态,有个值。这两个属性,我们是直接操作不了的。状态为“rejected”是因为调用了reject函数,值就是reject里面的参数。一图胜千言

promise对象,根据不同的函数调用,状态和值的变化。默认刚刚形成的promise对象,状态为“pending”,值为“undefined”

我们通过new Promise构造了promise对象,里面传递一个异步处理函数,一旦构造,就会执行这个异步函数,最后根据情况resolve或者reject函数改变他的状态和值。如下图:

promise本质明白了,说説其中几个注意的点:

  1. 一旦创建,无法中途取消
  2. reject返回一个错误,最好用Error对象,或者是继承它的对象
  3. 可以立即调用resolve或者reject(刚刚例子定时调用模拟耽搁时间),我们经常都是网络请求数据,中间会耽搁一些时间。
  4. 只会调用一个resolve或者reject,对于后面的都不会执行
  5. promise可以立即执行,但是js代码是从上到下,会先执行现行代码,遇到这些promise会先加入队列,执行完现行代码才执行promise这些操作

then/catch

.catch(f) 和 .then(null, f), then(undefined, f)类似 ,只是简写,如果只关心错误,那么可只用catch。

promise扩展——串行和并行

  • 串行:顾名思义就是一串的样子,链接形式
  • 并行:就是一起调用

先来看看串行:

var promise = new Promise(function (resolve, reject) {
    setTimeout(() => resolve(1), 1000);
}).then(function (result) {
    console.log(result);
    return result * 2;
});

看到上面的代码,第一个resolve返回的值为1,这时候其实是一个promise对象,值为1,然后又调用了then方法,result就是1,也就是上个promise的结果,最后返回了2,当然我们还可以继续往下,这就是链式调用。

并行:

看这样一个需求,假设我们现在想等几个promise都返回结果了,然后我们再处理一些操作,改怎么做呢?Promise.all

var pb1 = new Promise(function (resolve, reject) {
    setTimeout(resolve, 500, 'P1');
});
var pb2 = new Promise(function (resolve, reject) {
    setTimeout(resolve, 600, 'P2');
});
// 同时执行p1和p2,并在它们都完成后执行then:
Promise.all([pb1, pb2]).then(function (results) {
    console.log(results); // 获得一个Array: ['P1', 'P2']
});

最后我们可以看到返回了一个数组结果。将pb1和pb2promise作为参数同时传递进去。all,顾名思义也就是所有。

试想一下,如果我虽然同时要几个promise一起执行,但是呢,我只要首先返回结果的,后面的不要怎么弄?Promise.race

和all一样的调用方法,这里就不写了。race英文有竞赛的意思,也就是谁先返回就要谁。这里有人问了,那么返回了,后面的promise还会执行吗?答案是肯定的,还记得上面说的吗?promise一旦创建,就不能取消,当然还是会执行,只是结果没有用了。

参考资料

廖雪峰:https://www.liaoxuefeng.com/wiki/001434446689867b27157e896e74d51a89c25cc8b43bdb3000/0014345008539155e93fc16046d4bb7854943814c4f9dc2000

https://javascript.info/promise-basics

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值