异步编程
简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。
从语法上说,Promise 是一个对象,可以获取异步操作的消息。
promise两大特点:promise 对象的状态不受外界 ,且状态发生变化后不会再改变。
三个状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)
const promise = new Promise(function(resolve,reject){
if(........){
resolve(value)
}else{
reject(error)
}
})
resolve 表示状态从pending ->fulfilled reject表示状态从pending -> rejected
Promise.then()
表示propmise 状态改变之后的回调
第一个参数是resolved状态的回调函数,第二个参数是rejected状态的回调函数,都是可选的
Promise.catch()
Promise.finally()
执行完后,不管如何都会调用
promise
.then(result => {···})
.catch(error => {···})
.finally(() => {···});
promise.all()
const p = Promise.all([p1, p2, p3]);
p的状态有p1 、p2、p3的状态决定
只有p1 、p2、p3的状态都为fulfilled ;p的状态才能变更为fulfilled;其中一个出现rejected,则p的状态为rejected
Promise.race()
const p = Promise.race([p1, p2, p3]);
p1、p2、p3其中一个状态改变,P的状态就会随之改变
Promise.allSettled()
接收一组 Promise 实例作为参数,包装成一个新的 Promise 实例。只有等到所有这些参数实例都返回结果,不管是fulfilled还是rejected,包装实例才会结束
const promises = [
fetch('/api-1'),
fetch('/api-2'),
fetch('/api-3'),
];
await Promise.allSettled(promises);
removeLoadingIndicator();
Promise.any()
该方法接收一组 Promise 实例作为参数 race()与相似,其中一个状态变成成功fulfilled,状态就会变成fulfilled;但是只有所有的状态都变成rejected,总状态才会变成rejected
Promise.resolve()
将现有对象转化成promise 对象
const jsPromise = Promise.resolve($.ajax('/whatever.json'));
---------------------------------------------------------------------
Promise.resolve('foo')
// 等价于
new Promise(resolve => resolve('foo'))
resolve()的参数分为四种情况
(1)参数本身就是promise 对象时,不做任何改变,返回该实例
(2)参数是一个thenable对象
//具有then 方法的对象
let thenable = {
then: function(resolve, reject) {
resolve(42);
}
};
let p1 = Promise.resolve(thenable);
p1.then(function (value) {
console.log(value); // 42
});
//转化为peomise对象后,会立即执行thenable对象中的then对象
(3)参数没有then方法,或参数不是一个对象
如果参数是一个原始值,或者是一个不具有then()方法的对象,则Promise.resolve()方法返回一个新的 Promise 对象,状态为resolve
const p = Promise.resolve('Hello');
p.then(function (s) {
console.log(s)
});
// Hello
//由于不是对象,在生成promise对象的时候,其状态就为resolved
(4)不带有任何参数
Promise.resolve()方法允许调用时不带参数,直接返回一个resolved状态的 Promise 对象。
const p = Promise.resolve();
p.then(function () {
// ...
});
立即resolved 的对象是在本轮事件循环之后结束后执行
setTimeout(function () {
console.log('three');
}, 0);
Promise.resolve().then(function () {
console.log('two');
});
console.log('one');
// one
// two
// three
//console.log是在立即执行执行,resolve()是在本轮结束后执行,setTimeout是在下一轮开始后执行
所以输出 one tow three
Promise.reject()
Promise.reject(reason)方法也会返回一个新的 Promise 实例,该实例的状态为rejected。
const p = Promise.reject('出错了');
// 等同于
const p = new Promise((resolve, reject) => reject('出错了'))
p.then(null, function (s) {
console.log(s)
});
// 出错了
//reject会原封不动的返回rejected信息
Promise.try()
让同步函数同步执行,异步函数异步执行,并且让它们具有统一的 API
(1)ansyc
const f = () => console.log('now');
(async () => f())();
console.log('next');
// now
// next
//f 为同步
当f 为异步时 ,使用then 执行
(async () => f())()
.then(...)
.catch(...)
(2)new promise
const f = () => console.log('now');
(
() => new Promise(
resolve => resolve(f())
)
)();
console.log('next');
// now
// next
使用try()去代替上面的两种方法
//异步错误可以使用catch 去捕捉,但同步错误,需要使用try{} catch{}
//抛出异步错误时
database.users.get({id: userId})
.then(...)
.catch(...)
//抛出同步错误时
try {
database.users.get({id: userId})
.then(...)
.catch(...)
} catch (e) {
// ...
}
//可以统一使用promise.try包装
Promise.try(() => database.users.get({id: userId}))
.then(...)
.catch(...)