目录
Promise
Promise 是异步编程的一种解决方案,比传统的解决方案回调函数和事件更合理、更强大。
Promise 对象有以下两个特点。
(1)对象的状态不受外间的影响。Promise 对象代表着三种状态:pending(进行中)、fulfilled(已成功)和 rejected(已失败)只要有异步操作的结果,可以决定当前是哪种状态,任何其他操作都无法改变这个状态。
(2)一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise 对象的状态的改变,只有两种可能:从 pending 变为 fulfilled 和从 pending 变为 rejected。只要这两种情况发生,状态就固定了,不会在改变,会一直保持这个结果,这时就称为 resolved(已定型)。【可以将事件(Event)做对比。Promise 是,你再向该对象添加回调函数,也会立即得到这个结果。而事件,如果你错过了它,再去监听,是得不到结果的。】
优点:1. 可以将异步操作一同步的操作的流程表达出来,避免的层层嵌套的回调函数。 2. Promise 提供的统一的接口,是的异步操作更加容易。
缺点:1. 无法取消 Promise ,一旦新建他就立即执行,无法中途取消。 2. 如果不设置回调函数 Promise 内部抛出的错误,不会返回到外部。 3.当处于 pending 状态时,无法得知目前进展到哪一个阶段。
(例1)当在构造 Promise 的时候,构造函数内部的代码是立即执行的:
new Promise((resolve, reject) => {
console.log('new Promise')
resolve('success')
})
console.log('finifsh')
提示:下面要提到 .then() ,这里略提一下。
1. .then() 方法是异步执行。
2. 当 .then 前的方法执行完后在执行 then() 内部的程序,这样就避免了,数据没获取到等问题。
3.语法:promise.then(onCompleted(必须),onRejected(可选));
(例2)Promise 实现了链式调用,也就是说每次调用 then 之后返回的都是一个 Promise,并且是一个全新的 Promise,原因也是因为状态不可变。如果你在 then 中 使用了 return,那么 return 的值会被 Promise.resolve() 包装。
Promise.resolve(1)
.then(res => {
console.log(res) // => 1
return 2 // 包装成 Promise.resolve(2)
})
.then(res => {
console.log(res) // => 2
})
缺点:
(例3)下面执行结果为
const promise = new Promise((resolve, reject) => {
console.log(1);
console.log(2);
});
promise.then(() => {
console.log(3);
});
console.log(4);
最后应该输出1 2 4。这样最主要的就是3,要知道promise.then是微任务,会在所有的宏任务执行完之后才会执行,同时需要promise内部的状态发生变化,因为这里内部没有发生变化,所以不输出3。
async await
async 函数是什么?一句话,他就是 Generator 函数的语法糖。async/await 是ES7提出的基于Promise的解决异步的最终方案。
async 函数返回一个 Promise 对象,可以使用 then 方法添加回调函数。放函数执行的时候,一旦遇到 await 就会先返回,等到异步操作完成,再接着执行函数体后面的语句。
(例1)
async function getOne(name) {
const symbol = await
getTwo(name);
const stock = await
getThree(symbol);
return stock;
}
getOne('goog')
.then(function (result) {
console.log(result)
});
实际用法:
// 使用async/await获取成功的结果
// 定义一个异步函数,3秒后才能获取到值(类似操作数据库)
function getSomeThing(){
return new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve('获取成功')
},3000)
})
}
async function test(){
let a = await getSomeThing();
console.log(a)
}
test(); // 3秒后输出:获取成功