Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。它由社区最早提出和实现,ES6 将其写进了语言标准,统一了用法,原生提供了Promise
对象。
一、Promise对象的特点:
1、对象代表一个异步操作,不受外界影响,有三种状态:pending(进行时)、fulfilled(成功)、rejected(失败),只有异步操作结果,决定当前是哪种状态
2、状态一但改变就不会再变,对象的状态只有两种可能:成功、失败
二、基本使用
ES6 规定,Promise
对象是一个构造函数,用来生成Promise
实例。
const promise = new Promise(function(resolve, reject) {if(true) {resolve(value)}else {reject(error)}
})
Promise
构造函数接受一个函数作为参数,该函数的两个参数分别是resolve
和reject
。它们是两个函数,由 JavaScript 引擎提供,不用自己部署。
resolve
函数的作用是,将Promise
对象的状态从“未完成”变为“成功”(即从 pending 变为 resolved),在异步操作成功时调用,并将异步操作的结果,作为参数传递出去;reject
函数的作用是,将Promise
对象的状态从“未完成”变为“失败”(即从 pending 变为 rejected),在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。
Promise
实例生成以后,可以用then
方法分别指定resolved
状态和rejected
状态的回调函数。
promise.then(function(value) {// success
}, function(error) {// failure
});
then
方法可以接受两个回调函数作为参数。第一个回调函数是Promise
对象的状态变为resolved
时调用,第二个回调函数是Promise
对象的状态变为rejected
时调用。其中,第二个函数是可选的,不一定要提供。这两个函数都接受Promise
对象传出的值作为参数。
Promise 新建后就会立即执行。
let promise = new Promise(function(resolve, reject) {console.log('Promise');resolve();
});promise.then(function() {console.log('resolved.');
});console.log('Hi!');// Promise
// Hi!
// resolved
上面代码中,Promise 新建后立即执行,所以首先输出的是Promise
。然后,then
方法指定的回调函数,将在当前脚本所有同步任务执行完才会执行,所以resolved
最后输出。
调用resolve
或reject
并不会终结 Promise 的参数函数的执行。
new Promise((resolve, reject) => {resolve(1);console.log(2);
}).then(r => {console.log(r);
});
// 2
// 1
上面代码中,调用resolve(1)
以后,后面的console.log(2)
还是会执行,并且会首先打印出来。这是因为立即 resolved 的 Promise 是在本轮事件循环的末尾执行,总是晚于本轮循环的同步任务。
调用resolve
或reject
以后,Promise 的使命就完成了,后继操作应该放到then
方法里面,而不应该直接写在resolve
或reject
的后面。所以,最好在它们前面加上return
语句,这样就不会有意外。
new Promise((resolve, reject) => {return resolve(1);// 后面的语句不会执行console.log(2);
})
二、状态的写法种类
方式一、
const a = function() {return new Promise(function(resolve, reject) {if(!true) {resolve("成功")}else {reject("错误")}})
}
a()
.then(res => {console.log(res)
})
.catch(err => {console.log(err)
})
方式二、
const a = function() {return new Promise(function(resolve, reject) {if(!true) {resolve("成功")}else {reject("错误")}})
}a()
.then(res => {console.log(res)},err => {console.log(err)}
)