非常完美,小编今天又认识了一位新的伙伴,听说十分的友好,所以小编今天特地带它来见见大家 O(∩_∩)O 噢,它的名字叫“Promise”
一、简单介绍
在介绍Promise之前,小编得向大家解析几个名词
1.同步和异步
① 同步
当用户使用js和浏览器发生交互时,执行到某一个模块时系统发现需要向服务器提供网络请求,这个时候,js操作就会被阻塞,然后浏览器向服务器发送网络请求。
我们都知道网络请求的速度会比较慢,在此期间,不管用户执行任何操作,浏览器都不会去执行,因为此时的浏览器正在向服务器发送请求,没有空去理会别的操作,这就是同步,简单可以理解成浏览器的执行是按照某中顺序执行的,只有等上一步完成之后才会继续执行下一步操作。
② 异步
异步的含义和同步恰恰相反。当用户和浏览器发生交互,执行到某一模块的时候发现需要向服务器发送网络请求时,这个时候,浏览器向服务器发送请求之后,仍然可以执行别的操作。
当浏览器向服务器发送的请求得到回应后,我们一般会声明一个函数,将请求的结果放到该函数中,用户执行完某些操作后再回调该函数就可以得到向服务器发送网络请求的数据。
这就是异步,简单的可以理解成一心二用:一边向服务器发送请求,一边执行相关的操作,最后通过回调某个函数来得到向服务器发动请求的数据。如果只是一个简单的网络请求,这种方案没有什么麻烦,但是当网络请求变得复杂的时候,就会出现回调地狱 Σ(⊙▽⊙"a
2.回调地狱
简单的理解就是函数的迭代。我们举一个简单的例子。比如:
我们需要通过一个url1从服务器加载一个数据data1,发现data1并不是最终的结果而是包含了下一个请求的url2,然后通过data1取出url2,从服务器加载数据data2,data2中包含了下一个请求的url3,接着通过data2取出url3,从服务器加载数据data3,data3中包含了下一个请求的url4,最后发送网络请求url4,获取最终的数据data4。
但是如果我们用Promise就不会出现回调地狱,下面我们一起看看什么是promise以及语法是什么
二、基本语法
1.基本定义
Promise是异步编程的一种解决方案。它是一个类,可以通过new的方式创建一个对象。
2.使用场景
正如它的基本定义一样,一般用在异步请求的场合,并且会将请求数据的模块放在一个地方,处理数据的模块放在另外一个地方,就不会像之前回调函数一样,将请求url数据和处理data1数据都放在同一个地方,小编在下面会给出具体的代码,目前只需要明白两点:
第一:promise用来处理异步编程
第二:promise将请求模块和处理模块分开
下面我们来看看promise如何使用
3.使用语法
① 使用new创建
我们知道promise是一个类,所以我们可以通过new的方式来创建promise,并且创建的promise是一个函数
② 传入参数
当我们通过new方式创建promise函数时,就会被要求传入两个参数:resolve和reject,而这两个参数本身又是一个函数
③ then函数
我们创建完promise之后,将有关的请求数据放在promise内部,然后将处理数据放在then函数,并且当用户执行了resolve函数就会调用then函数。更神奇的是,then本身又是一个函数。
有点抽象,我们看看下面的例子:
setTimeout({
console.log('hello,vue');
},1000)
以setTimeout为异步事件,经过一秒中后就打印“hello,vue”语句,我们可以假定 setTimeout 函数是向服务器发送的请求,而console.log('hello,vue')是对服务器发送请求的处理,下面使用promise封装过程如下:
第一:声明promise,并将异步事件全部丢到promise函数中
new Promise((resolve,reject)=>{
setTimeout({
console.log('hello,vue');
},1000)
})
上述代码中,创建了promise函数,两个参数resolve和reject由于本身又是一个函数,所以在这里使用箭头函数来声明,然后将异步事件全部丢进promise函数内部中。
第二:封装数据
new Promise((resolve,reject) =>{
setTimeout(()=>{
resolve()
},1000)
}).then(()=>{
console.log('hello,vue')
})
上述代码中,setTimeout函数看作请求,该请求是经过1秒后执行打印语句,将请求放在了promie内部,然后打印语句看作是对请求的处理,放在了then函数中。执行顺序如下:首先进入到promise内部,经过一秒中后执行resolve函数,该函数就会回调then函数,执行then函数内部的打印语句。其效果如下:
在控制台中确实执行了打印语句。
是的,或许有会小伙伴问到,如果网络数据请求失败了怎么办?没关系,Promise中还有另外两个函数 reject 和catch。
reject的用法和resolve的用法是一样的,不一样的是,当请求某些数据失败的时候就会执行reject函数,该函数就会回调catch函数,具体代码如下:
<script>
new Promise((resolve,reject) =>{
setTimeout(()=>{
reject()
},1000)
}).catch(()=>{
console.log('error')
})
</script>
因此,针对上述的内容,我们知道,Promise会将不同的处理交给不同的函数去执行,如果网络请求成功,就执行resolve函数,然后回调then函数;如果网络请求失败,就会执行reject函数,然后回调catch函数。所以代码的逻辑就变得十分的清晰明了。
如果现在体会不到promise的好处,可以往下看看彩蛋,保证震惊到你(✿◡‿◡)因为不细心的人可能看不懂
好了,今天小编就到这里啦,谢谢大家伙,后面有彩蛋噢,还等什么,看彩蛋来挑战自己吧。
<script>
new Promise((resolve,reject) =>{
setTimeout(()=>{
resolve()
},1000)
}).then(()=>{
console.log('hello,vue')
return new Promise((resolve,reject) =>{
setTimeout(()=>{
resolve()
},1000)
})
}).then(() =>{
console.log('hello,java')
return new Promise((resolve,reject) =>{
setTimeout(()=>{
resolve()
},1000)
})
}).then(() =>{
console.log('hello,JavaScript')
})
</script>
这个就是用promise改变过后的回调地狱,你看懂了嘛o( ̄︶ ̄)o