持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第3天,点击查看活动详情
前端开发同步和异步的区别
同步:一般指的是在代码运行的过程中,从上到下逐步运行代码,每一部分代码运行完成之后,下面的代码才能开始运行异步:指的是当我们需要一些代码在执行的时候不会影响其他代码的执行,也就是在执行代码的同时,可以进行其他的代码的执行,不用等待代码执行完成之后才执行之后的代码,就像我们人一样,可以一边看电视剧一边吃东西一样,互不干扰,这种方式就是异步。
而在前端开发中常见的异步一般常见的包括:setTimeout,setInterval,ajax。
-
setTimeout是定时延时运行函数,只执行一次
-
setInterval也是定时延时函数,但是这个函数本身可以一直执行,不会停止,除非把它清除。
-
ajax是前端常用的和后台进行异步交互数据的请求方式,其实它本身也包括同步和异步,同步的就是由代码从上到下顺序执行,而异步的ajax是我们发送请求到服务器之后,只需要在监听服务器的响应即可,不用等到请求结束在执行其他的代码,这就是异步ajax。
Promise 的含义
Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和强大
所谓Promise,从语法上说,Promise是一个对象,从它可以获取异步操作的消息。简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。
Promise 的三种状态
(敲黑板!记住!这三种状态,考试要考的)
pending(进行时)fulfilled(已成功)rejected(已失败)
Promise 的两个特点
-
对象的状态不受外界影响:
Promise对象代表一个异步操作。对于三种状态,只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。Promise(承诺)的由来 -
一旦状态改变,就不会再变,任何时候都可以得到这个结果:
Promise对象的状态改变,只有两种可能:从pending变为fulfilled和从pending变为rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果,这时就称为 resolved(已定型)。
(特别说明:为了我瞎扯下文的方便后面的resolved统一只指fulfilled状态,不包含rejected状态。)
Promise API
(有点多,耐心看,挑重点)
Promise.resolve()
有时需要将现有对象转化为
Promise对象,Promise.resolve()方法就起了这个作用
将状态从pending转化为fulfilled
Promise.resolve 方法的参数分成四种情况:
-
参数是一个
Promise实例
如果参数是一个 Promise 实例,那么 Promise.resolve 将不做任何修改,原封不动地返回这个实例。
-
参数是一个
thenable对象
thenable对象指的是具有then方法的对象,实例如下:
let thenable = {
then:function(resolve,reject) {
resolve(666)
}
}
Promise.resolve方法会将这个对象转为 Promise 对象,然后就立即执行thenable对象的then方法。
1. let thenable = {
2. then: function(resolve, reject) {
3. resolve(666);
4. }
5. };
6. let p1 = Promise.resolve(thenable);
7. p1.then(function(value) {
8. console.log(value); // 666
9. });
上面代码中,第6行代码执行完,对象p1的状态就变为 resolved,从而立即执行最后那个then方法指定的回调函数,输出 666
-
参数不是具有
then方法的对象,或者压根就不是对象
如果参数是一个原始值。也就是说参数是“hello world”,"1","2"....这种原始值,或者说不像上面所说的是一个不具有then方法的对象,则方法返回的是一个新的Promise对象,但是!状态已经发生了改变,变成了resolved,例子如下:
const p = Promise.resolve('小鳄鱼加油!');
p.then(function() {
....
})
【特殊说明:判断参数内的玩意儿(对象)属不属于异步操作的方法是: 其具不具备 then 方法】
由于上面的字符串小鳄鱼加油!不属于异步操作,返回最新的Promise实例的状态从一生成就是resolved,回调函数会立即执行。Promise.resolve方法的参数,会同时传给回调函数
-
不带有任何参数
Promise.resolve()方法允许调用时不带参数,直接返回一个resolved状态的 Promise 对象。
这是一个很方便快速得到一个 Promise 对象的方法
resolve()的注意点
话不多说直接上代码!
setTimeout(function() {
console.log('3')
})
Promise.resolve().then(function() {
console.log('2')
})
console.log('1')
// 1
// 2
// 3
上面代码中,setTimeout(fn, 0)在下一轮“事件循环”开始时执行,Promise.resolve()在本轮“事件循环”结束时执行,console.log('one')则是立即执行,因此最先输出。
Promise.reject()
将状态从pending转化为rejected
Promise.reject(reason)方法与上述的Promise.resolve()相同,也会返回一个新的 Promise 实例,该实例的状态为rejected。
const p = Promise.reject('出错了!')
p.then(null.function(s) {
console.log(s) // 出错了
})
上面代码生成一个 Promise 对象的实例p,状态为rejected,回调函数会立即执行。
注意:Promise.reject("猫南北"),里面的 ‘猫南北’ 会原封不动地作为reject的理由,这玩意会变成后续方法的参数。
这一点与 Promise.resolves方法是不一致的
看下面的代码就知道了
const thenable = {
then(resolve,reject) {
reject('猫南北')
}
}
Promise.reject(thenable).catch(e => {
console.log(e === thenable)
})
// true
上面代码中,Promise.reject方法的参数是一个thenable对象,执行以后,后面catch方法的参数不是reject抛出的“猫南北”这个字符串,而是thenable对象。
应用
- 加载图片
- Generator 函数与 Promise 的结合