promise概念
我们先从定义入手,ES6中promise是什么,我们用它来干什么?
Promise 是异步编程的一种解决方案: 从语法上讲,promise是一个对象,从它可以获取异步操作的消息;从本意上讲,它是承诺,承诺它过一段时间会给你一个结果。
promise有三种状态:
- pending(等待态)
- fulfiled(成功态)
- rejected(失败态)
状态一旦改变,就不会再变。创造promise实例后,它会立即执行。
promise是用来解决两个问题的:
- 回调地狱,我们看一个简单的函数嵌套函数,这样还是只有一层,多了的话嵌套起来会比较麻烦也难以维护我们就可以使用promise解决
function fn1(a, fn2) { if (a > 10) { fn2() } } fn1(11, function() { console.log('this is a callback') }) - promise可以支持多个并发的请求,获取并发请求中的数据
promise用法
Promise构造函数
Promise是一个构造函数,自己身上有all、resolve、reject这几个方法,原型上有then、catch供我们实现嵌套。我们还是像往常一样先创建一个简单的案例然后慢慢分析实现。
let promise = new Promise((resolve, reject) => {
setTimeout(() => {
console.log('执行完成');
resolve('接收成功执行');
}, 1000);
})
这边我们要注意一下Promise构造函数的参数,是一个函数该函数参数为resolve和resolve
then、catch方法
Promise生成的对象用then方法对应resolve,这样的条件嵌套更加方便维护而且更加明了,同样的catch对应reject,而且catch方法会捕获错误而不会因为代码问题终止程序,我们看一个实际异步案例
let p = new Promise((resolve, reject) => {
//做一些异步操作
setTimeout(function(){
var num = Math.ceil(Math.random()*10);
if(num<=5){
resolve(num);
}
else{
reject('数字太大了');
}
}, 1000);
});
p.then((data) => {
console.log(data);
return data
}
).catch((err) => {
console.log(err);
}
)
.then((data) => {
console.log(data);
})
Promise的all方法
这边就简单提及一下Promise的all方法可以综合promise对象生成一个新的对象,然后要all中所有对象都成功则成功。
手写Promise
创建Promise类
小编这边简单的实现一下手写Promise,包括执行器包括的resolve,reject方法,then、catch方法,感受一下内置流程
// 创建promise类
class Promise {
constructor (executor){
//默认状态是等待状态
this.status = 'panding';
this.value = undefined;
this.reason = undefined;
//存放成功的回调
this.onResolvedCallbacks = [];
//存放失败的回调
this.onRejectedCallbacks = [];
let resolve = (data) => {//this指的是实例
if(this.status === 'pending'){
this.value = data;
this.status = "resolved";
this.onResolvedCallbacks.forEach(fn => fn());
}
}
let reject = (reason) => {
if(this.status === 'pending'){
this.reason = reason;
this.status = 'rejected';
this.onRejectedCallbacks.forEach(fn => fn());
}
}
try{//执行时可能会发生异常
executor(resolve,reject);
}catch (e){
reject(e);//promise失败了
}
}
}
实现then方法
then(onFulFilled, onRejected) {
if (this.status === 'resolved') { //成功状态的回调
onFulFilled(this.value);
}
if (this.status === 'rejected') {//失败状态的回调
onRejected(this.reason);
}
}
promise常见考题
执行顺序
const promise = new Promise((resolve, reject) => {
console.log(1)
resolve()
console.log(2)
})
promise.then(() => {
console.log(3)
})
console.log(4)
这边我们注意promise对象是创建及执行,而then方法是异步的。
resolve、reject方法
const promise = new Promise((resolve, reject) => {
resolve('success1')
reject('error')
resolve('success2')
})
promise
.then((res) => {
console.log('then: ', res)
})
.catch((err) => {
console.log('catch: ', err)
})
构造函数中的 resolve或reject只有第一次执行有效,多次调用没有任何作用,promise 状态一旦改变则不能再变,这边也提及一点.then 或 .catch 返回的值不能是 promise 本身,否则会造成死循环。
async、await
如果 Promise 的回调中出现嵌套,依旧会出现回调地狱;而如今,async await 出现了,它提供了一种新的编写异步代码方式,使得异步代码看起来像是同步代码。
async
异步函数声明很简单,但调用异步函数时它自动返回的是一个Promise对象
async function show() {
return 'getshow';
}
show().then((data) => {
console.log(data);
})
await
await 操作符用于等待一个 Promise 返回结果或者某个直接的值,且 await 必须在异步函数 (async function) 上下文中使用。功能很明确在碰到await一个promise时,暂停等待Promise返回值然后函数在往下进行。
let promise = new Promise((resolve, reject) => {
setTimeout(() => {
console.log('执行完成');
resolve('接收成功执行');
}, 1000);
})
async function show() {
let test = await promise;
return test;
}
show().then((data) => {
console.log(data);
})
总结
小编这边主要是总结了一下Promise概念以及用法,也简单的总结了一下async,await用法,手写部分功能是不够完善的,只是自己以类方法感受一下内部流程,下一篇文章小编总结复习一下Service Worker / PWA