浅入Promise

189 阅读3分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

Promise 在JavaScript的世界里占有很高的地位,了解掌握promise是每个学JavaScript的人必须要会的,所以笔者今天学习了 Promise ,以写文章的形式记录自己的学习情况。

同步与异步

我们都知道JavaScript是一门单线程语言,那么这就让它就涉及到异步编程;当然我在这里简单的说明一下同步与异步。什么是同步:在js中每条指令都严格的按照它的出现的顺序来执行,就比如:

let x=3;
let y=4;
x=x+3;
y=y+x;
//最后的结果为10

这样按照从上到下依次执行就叫同步执行

那么什么是异步呢?

简单的来说就是如果一个程序要执行或者等待很久,它后面的程序就不等它了,从而继续的执行这个要等待很久的程序后面的程序;这样子就叫异步,那么举个例子给大家看

function a(){
    console.log('aaa');
}

function b(){
    setTimeout(()=>{
        console.log('bbb');
    },1000)
}


function c(){
    console.log('ccc');
}

a()
b()
c()

你认为这段代码的执行结果会是啥?先打印aaa再打印bbb最后再打印ccc? nonono ,看结果:

QQ图片20220719215944.png

先打印出aaa再打印出ccc,并且最后一个bbb还是等待了那么一会时间才打印出来的,没想到吧。事实上函数a()执行完打印aaa,当碰到函数b()时,里面有个定时器,这就会导致延迟一秒执行函数b(),而此时函数c()先执行了,先打印出ccc再打印出bbb,这就是异步。 你看这样是不是就理解了异步。

怎么解决异步?

上面的执行结果是不是看起来很不舒服?要是能让他先输出aaa再输出bbb最后输出ccc就好了。所以我们该怎么做呢? 其实只要使用回调函数就好了,你看:

function a(){
    console.log('aaa');
}

function b(cb){
    setTimeout(()=>{
        console.log('bbb');
        cb();
    },1000)
}


function c(){
    console.log('ccc');
}

a()
b(c)

结果如下:

QQ图片20220719221303.png

你看在函数b()里面传入c函数,当计时器过了一秒钟之后先打印bbb,然后再打印ccc,这样就解决了异步问题。 所以使用回调函数是个不错的解决方案。但是这种方法有一种致命的缺点:会产生回调地狱(callback hell)也叫毁灭金字塔(pyramid of doom)

回调地狱?

我就说的浅显一点:当函数b在函数a里面调用,因为只有当函数b执行完成后函数a才能执行完,如果函数b里面又有函数c调用,函数c里面又有函数d调用...这样嵌套过深,那么就会导致嵌套在外面的函数的执行上下文一直没有被回收,这样就会一直占用内存,就可能导致爆栈,这就是所谓的回调地狱

那么那么更为优雅的方法就是使用Promise:

function a(){
    console.log('aaa');
}

function b(){
//promise自带两个参数,一个resolve跟reject;当函数读取成功了,就会返回resolve,失败了就会返回reject;
    return new Promise((resolve,reject)=>{
        setTimeout(()=>{
            console.log('bbb');
            resolve('读取成功')
            reject('读取失败')
        },1000)
    })
}


function c(){
    console.log('ccc');
}

a()
b().then((res)=>{
    console.log(res);
    c()
})//现在b函数可以使用.then;只有当一个函数return了一个Promise才可以使用.then()

执行结果:

QQ图片20220719224321.png

你看这样写是不是就优雅了很多,而且也解决了回调地狱这个问题。本文只是浅浅的介绍了Promise的使用场景以及一些相关的知识,如果有不对的地方欢迎大家指出。