Promise
Promise是ES6提出解决异步编程的方案,相比于传统的回调函数,Promise更符合人们的编程习惯,也更强大。Promise是一个对象,通常会保存着异步操作的结果。
Promise有两大特点:
- Promise的结果不受外界影响,只跟异步操作的结果有关。Promise对象代表一个异步操作,有三种状态:pending、fulfilled和rejected。
- Promise一旦发生状态改变,则不会再发生变化。也就是从pending变成fulfilled或rejected之后就再也不会发生变化了。
Promise的优点:
- 不用再写地狱回调了,将异步操作用同步的方法表示出来。
- Promise提供了统一的API,可以比较方便的控制异步操作。
Promise的缺点:
- Promise一旦开始执行就无法中途取消。
- Promise无法得知内部的执行情况,无法得知异步是刚开始执行还是已经快执行结束了,也无法捕捉内部抛出的异常。
Promise的语法
Promise对象是一个构造函数,用来生成Promise实例。Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolve和reject。
const promise = new Promise (function (resolve,reject){
var img = document.createElement('img');
img.onload = function(){
resolve(img);
}
img.onerror = function(){
reject();
}
img.src = src;
})
resolve函数的作用是,将Promise对象的状态从 pending 变为 resolved,在异步操作成功时调用,并将异步操作的结果,作为参数传递出去;
reject函数的作用是,将Promise对象的状态从 pending 变为 rejected,在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。
Promise实例生成后,可以使用then方法分别指定resolved状态和rejected状态的回调函数。
promise.then(function(img){
console.log(img.width) //sucess
},function(){
console.log('failed') //failed
})
接下来举个例子,使用Promise包装了一个图片加载的异步操作。如果加载成功,就调用resolve方法,否则就调用reject方法。
function loadImg(src){
const promise = new Promise (function (resolve,reject){
var img = document.createElement('img')
img.onload = function(){
resolve(img)
}
img.onerror = function(){
reject()
}
img.src = src
})
return promise //一定要return
}
var src = 'https://www.baidu.com/static/img/index/logo_new.png'
var result = loadImg(src)
result.then(function(img){
console.log(img.width)
},function(){
console.log('failed')
})
如果调用resolve或reject函数时带有参数,那么它们的参数会被传递给回调函数。reject函数的参数通常是Error对象的实例,表示抛出的错误;resolve函数的参数除了正常的值以外,还有可能是其他的 Promise 实例。
const promise1 = new Promise(function (resolve, reject) {
// ...
});
const promise2 = new Promise(function (resolve, reject) {
// ...
resolve(promise1); //promise2异步操作的结果是返回promise1异步操作的结果
})
通常来说,调用resolve或reject以后,Promise 就应该完成了,接下来的操作应该放到then方法里面,而不应该直接写在resolve或reject的后面。所以,建议在它们前面加上return语句,这样就不会去执行后面的语句了。
new Promise((resolve, reject) => {
return resolve(1); //建议加上return
// 后面的语句不会执行
console.log(2);
})
then
then方法的作用是为 Promise 实例添加状态改变时的回调函数,then方法是定义在原型对象Promise.prototype上的。
then方法的第一个参数是resolved状态的回调函数,第二个参数(可选)是rejected状态的回调函数。