本文已参与「新人创作礼」活动,一起开启掘金创作之路。
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 ,看结果:
先打印出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)
结果如下:
你看在函数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()
执行结果:
你看这样写是不是就优雅了很多,而且也解决了回调地狱这个问题。本文只是浅浅的介绍了Promise的使用场景以及一些相关的知识,如果有不对的地方欢迎大家指出。