1.promise的含义
promise是一个异步编程方案,最初由社区提出,用来解决回调地狱,后面ES6写进了语言标准,统一了语法
两个特点:
① 状态不受外界影响,promise代表一个一步操作,有三个状态:
pending(进行时),fulfilled(已成功),rejected(已失败)
② 状态一旦改变,就不能再变:
promise对象改变只有两种可能: 从pending(进行时)变为fulfilled(已成功) 从pending(进行时)变为rejected(已失败)
缺点:
① 无法取消Promise,一旦新建它就会立即执行,无法中途取消
② 如果不设置回调函数,Promise内部抛出的错误,不会反应到外部
③ 当处于pending状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)
2.promise的基本用法
实例方法:
then:用来指定成功和失败的回调 (当状态改变时,才会推入微任务队列)
创建promise实例:
new Promise((resolve,reject) => {
//resolve(data):
用来标记已完成,data是成功的数据,then方法成功的回调函数的形参可以接收
//reject(reason)
用来标记已失败,reason是失败的原因,then方法错误的回调函数的形参可以接收
}).then((data)=>{
//success 成功
},(reason)=>{
//fail 失败 })
resolve函数: 将Promise对象的状态从“未完成”变为“成功”
Promise函数: 将Promise对象的状态从“未完成”变为“失败”
Promise对象的简单例子(函数封装):
function timeout(ms) {
return new Promise((resolve, reject) => {
setTimeout(resolve, ms, 'done'); //经过ms秒后,将'done'传给resolve
});
}
timeout(3000).then((value)=>{
console.log(value); // 'done'
})
return的用法:
var p = Promise.resolve(1)
var p2 = p.then((data)=>{
console.log(data) // 1 return p //如果不return p 的话,p3打印的data返回则是undefined
})
var p3 = p2.then((data)=>{
console.log(data) // 1
})
3.Promise.resolve()
作用:将现有对象转为 Promise 对象
例如将 jQuery 生成的deferred对象,转为一个新的 Promise 对象:
const jsPromise = Promise.resolve($.ajax('/whatever.json'));
Promise.resolve()等价于下面的写法:
Promise.resolve('foo')
// 等价于
new Promise(resolve => resolve('foo'))
Promise.resolve()方法的参数分成四种情况:
① 参数是一个 Promise 实例
Promise.resolve将不做任何修改、原封不动地返回这个实例
② 参数是一个 thenable 对象
thenable对象指的是具有then方法的对象,比如下面这个对象:
let thenable = {
then: function(resolve, reject) {
resolve(42);
}
};
③ 参数不是具有then()方法的对象,或根本就不是对象
--返回一个新的 Promise 对象,状态为resolved
let thenable = {
then: function(resolve, reject) {
resolve(42);
}
};
--Promise.resolve()方法会将这个对象转为 Promise 对象,然后立即执行 thenable对象的then()方法:
let thenable = {
then: function(resolve, reject) {
resolve(42);
}
};
let p1 = Promise.resolve(thenable);
//当thenable对象then()方法执行后,对象p1为resolved状态
p1.then(function (value) {
console.log(value); // 42
});
④ 不带有任何参数
直接返回一个resolved(已成功)状态的 Promise 对象
得到一个 Promise 对象: const p = Promise.resolve();
案例:
setTimeout(function () {
console.log('three');
}, 0);
Promise.resolve().then(function () {
console.log('two');
});
console.log('one');
// 打印顺序: one => two => three
利用promise解决回调地狱:
宏队列与微队列
宏列队:
用来保存待执行的宏任务(回调),比如:定时器回调、DOM 事件回调、ajax 回调
微列队:
用来保存待执行的微任务(回调),比如:promise的回调、MutationObserver 的回调
微列队的执行优先级大于宏列队
promise(微任务) --- setTimeout(宏任务) 有微任务先执行优先级比宏任务高
promise的回调函数,必须等待其状态改变后,才会进入微任务队列
then 实例方法:用来指定成功和失败的回调(当状态改变时,才会推入微任务队列)
返回一个新的promise 对象
.then指定的函数中的返回值,会作为其创建出来的新的promise对象的成功的值