首先,大家都知道的是 JavaScript是单线程语言,而且代码是异步执行的,也就是说它无法保证代码执行的顺序。
遇到的问题:
setTimeout(()=>{
console.log('在忙----');
},2000)
console.log('hello world')
//输出结果:hello world
在忙---
(小提示:setTimeout名为计时器,用来指定某个函数或某段代码,在多少毫秒之后执行,上面这段代码是延迟2秒执行)
可以看到,明明console.log('在忙----')在console.log('hello world')前面,可是它竟然出现在了后面,有点奇怪。
带着不解,探索了下这个问题。
找到原因:
因为JS是单线程语言(跟开头连上啦),它的执行顺序是遵循一个叫做事件队列的机制,当JS代码运行到setTimeout这里时,会开启一个定时器进程,然后执行下一个代码。由此可以给setTimeout一个定义:在指定时间内, 将任务放入事件队列,等待js引擎空闲后被执行.
解决办法:(本章重点来了)
使用Promise构造函数,它可以将异步操作以同步操作的流程表达出来。也就是说它可以让上面例子中console.log('在忙----')先执行。
上例子:
const per =new Promise((resolve,reject)=>{
//resolve: 解决了问题 reject :问题没解决
console.log('在忙----');
setTimeout(()=>{
resolve('天天年年的我们')
},2000)
})
per
.then((res)=>{
console.log(res);
})
//输出结果:在忙----
天天年年的我们
不得不说,有点厉害(手动给Promise点赞👍)
再了解了解Promise吧
—— 它的英语翻译是“许诺”,一旦许下承诺,就不可以再改变了。这也意味着,一旦Promise对象的状态改变了,就不会再变了 。
Promise的构造函数接收一个参数(是函数,函数中是一些耗时的任务),并且传入两个参数:resolve,reject,它们分别表示异步操作执行成功后的回调函数和异步操作执行失败后的回调函数。其实这里用“成功”和“失败”来描述其实并不准确,按照标准来讲,resolve是将Promise的状态置为fullfiled,reject是将Promise的状态置为rejected。
Promise身上有all,resolve,reject方法(这里只说后两个),原型上有then,catch方法。所以上面的例子中通过Promise new出来的对象Per上也有then和catch方法。
-
then():作用是添加回调函数then()方法可以有两个参数(第二个可选)- 第一个是
resolve状态的回调函数(必选) - 第二个是
reject状态的回调函数(可选)
在将
Promise对象改为resolve状态的时候调用,可以让then()前面的代码先执行。 - 第一个是
-
catch(): 它是.then(null, rejection)或.then(undefined, rejection)的别名。也就是说,catch()也是一种then(),它的作用是捕获错误,是then的第二个参数。
const per =new Promise((resolve,reject)=>{
//resolve 解决了问题
//reject 问题没解决
console.log('在忙----');
setTimeout(()=>{
reject('小姐姐正在努力抢救服务器')
},2000)
})
per
.catch((msg)=>{
console.log(msg);
})
//输出结果:在忙----
小姐姐正在努力抢救服务器
promise的使用方法:
new一个promise对象- 将要执行的异步函数传入到
Promise的参数中执行(将你不想某个耗时任务被跳过执行时,封装到函数内部) - 并且在异步执行结束后调用
resolve( )函数或者reject()函数,这样就可以得到异步函数的执行结果啦。