Promise

Promise 是 ES6 提供的一种异步编程的解决方案: 将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数(解决异步函数回调地狱的问题)。
Promise 对象保存着异步操作的结果。

首先看异步的概念,这在《ECMAScript6入门》中介绍的很好:

所谓"异步",简单说就是一个任务不是连续完成的,可以理解成该任务被人为分成两段,先执行第一段,然后转而执行其他任务,等做好了准备,再回过头执行第二段。

比如,有一个任务是读取文件进行处理,任务的第一段是向操作系统发出请求,要求读取文件。然后,程序执行其他任务,等到操作系统返回文件,再接着执行任务的第二段(处理文件)。这种不连续的执行,就叫做异步。

相应地,连续的执行就叫做同步。由于是连续执行,不能插入其他任务,所以操作系统从硬盘读取文件的这段时间,程序只能干等着。

而JS对异步编程的实现就是通过回调函数(把任务的第二段单独写在一个函数里面,等到重新执行这个任务的时候,就直接调用这个函数),回调函数本身并没有问题,问题就在于嵌套的形式容易因为层次太深而变得混乱难以维护(多个异步操作形成了强耦合,只要一个曹组哦需要修改,它的上层和下层回调函数都要跟着修改),因此为了解决这个问题,Promise 采用了新链式写法,使得任务不同的执行阶段变得清晰。

Promise 特点:

  1. 其状态不受外界影响:
     Pending: 进行中
     Fulfilled: 已成功
     Rejected: 已失败
  2. 状态一旦改变便不会再变。
     Pending -> Fulfilled: Resolved => then(res => {…})
     Pending -> Rejected: Rejected => catch(err => {…})

创建一个 Promise 实例

var promise = new Promise((resolve, reject) => {
if (success) {
resolve(value)
} else {
reject(error)
}
})
promise.then(value => {…}, error => {…})
Promise 新建后就会立即执行

resolved 的 Promise 是在本轮事件循环的末尾执行,总是晚于本轮循环的同步任务。

调用resolve或reject以后,Promise 的使命就完成了,后继操作应该放到then方法里面,而不应该直接写在resolve或reject的后面。所以,最好在它们前面加上return语句,这样就不会有意外。

new Promise((resolve, reject) => {
return resolve(1);
// 后面的语句不会执行
console.log(2);
})
Promise.prototype.then()

为 Promise 实例添加状态改变时的回调函数。then 方法的第一个参数是 Resolved 状态的回调函数,第二个参数(可选)是 Rejected 状态的回调函数(更多的是直接写成 catch 方法)。
then方法返回的是一个新的 Promise 实例(注意,不是原来那个 Promise 实例)。因此可以采用链式写法,即 then 方法后面再调用另一个 then 方法。

getJSON("/posts.json").then(function(json) {
return json.post;
}).then(function(post) {
// …
});
promise 中的 then 和 catch 方法可以交换位置,但是执行顺序也会被交换,如果在 then 方法中报错,在前面的 catch 中就无法捕获了。
catch 中可以继续抛出错误,因此 catch 后面可以继续写 catch 方法来捕获错误。

Promise.all()

var p = Promise.all([p1, p2, p3])

p1, p2, p3 都是 Promise 实例,只有这些实例的状态都变成 fulfilled ,p 的状态才会变成 fulfilled,否则只要有一个实例的状态变成 rejected,这个实例被 rejected 返回的值就会传递给 p

done()

Promise 对象的回调链,最后一个方法(then 或 catch)抛出的错误都无法被捕获,因此可以在回调链末尾使用 done 方法来处理抛出的错误。

asyncFunc()
.then(f1)
.catch(r1)
.then(f2)
.done();
finally()

用于指定不管 Promise 对象最后状态如何都会执行的操作。

server.listen()
.then(function () {
// run test
})
.finally(server.stop);
一.同步与异步

  1. Promise作用:解决异步回调的问题
    二.Promise对象
    目的:创建异步对象,当异步对象中的异步操作执行完之后,再执行想要执行的东西。

  2. resolve 表示将状态变成成功完成,reject 表示将状态变成失败完成。

  3. 当resolve方法执行完成之后,再执行then方法。
    let p = new Promise((resolve,reject)=>{
    setTimeout(()=>{
    console.log(‘执行完毕!’);
    resolve();
    //表示完成
    },3000)
    });
    p.then(()=>{
    console.log(‘promise异步操作完成了’);
    });
    三.Promise传参
    resolve里的参数可以传给then
    let p = new Promise((resolve,reject)=>{
    setTimeout(()=>{
    //console.log(‘脱完衣服’);
    resolve(3);
    },3000)
    });
    p.then((d)=>{
    console.log(‘去洗’+d+‘件衣服’);
    });
    –>打印去洗3件衣服
    四.Promise错误处理

  4. reject中存储错误处理的参数,可以传给then方法中的第二个参数
    let p = new Promise((resolve,reject)=>{
    setTimeout(()=>{
    //resolve(‘读写成功’);
    reject(‘读写失败’);
    },2000)
    });
    p.then((d)=>{
    console.log(‘执行成功’);
    },(err)=>{
    console.log(err);
    });
    –>读写失败
    五.Promise.all()–>一个脚本中有多个promise时,监控多个Promise对象执行完成
    1.Promise.all([p1,p2,p3]):把promise打包,扔到一个数组里面,打包完还是一个promise对象.
    let p1 = new Promise((resolve,reject)=>{
    let time = Math.random()*4000+1000;
    setTimeout(()=>{
    console.log(‘p1完成’);
    resolve();
    },time)
    });
    let p2 = new Promise((resolve,reject)=>{
    let time = Math.random()*4000+1000;
    setTimeout(()=>{
    console.log(‘p2完成’);
    resolve();
    },time)
    });
    let p = Promise.all([p1,p2)];
    p.then(()=>{
    console.log(全部执行完毕);
    })
    –>p1和p2全部执行完毕后,才会执行p.then方法里的操作
    必须确保所有promise对象都是resolve状态

输出[“aaaa”,“bbbb”,“cccc”]
六.
1.Promise对象的then方法有两个参数,一个是成功后的参数,另一个是失败的参数方法
promise.then(success,fail)
失败鸟
2.new Promise().catch()–>错误捕获
等同于上面的reject,返回“失败鸟”
也可这样使用
七.Promise的方法
1.Promise.resolve(‘xxx’):将现有的东西,转成一个Promise对象,且是resolve成功状态
输出aaa
2.Promise.reject(‘xxx’):将现有的东西,转成一个Promise对象,且是reject失败状态
输出aaaa
4.Promise.race():与all的不同之处在于,只要有一个是resolve状态就可以返回
输出aaaa

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值