回调函数
对比-普通函数和异步函数返回值
- 普通函数的直接返回想要的数据,可以异步函数不行,于是便有了回调函数.
进化-回调函数
例子1
- 以前是我希望调用你这个函数,然后能够给我返回一些数据,在我这里进行处理,但是我拿不到数据
- 现在呢,我调用你这个函数,感觉我把怎么处理这些数据的流程都告诉你了,然后在你那里处理数据吧.
- 或者这样理解,以前,数据的处理流程和执行流程都在我这里
- 现在,我把数据的处理流程告诉你,然后在你那里进行执行
例子2
-
如果requestData()是个普通函数,也就是里面没有异步代码,那么我在20行调用这个函数,就是希望这个函数能够返回某个结果来让我进行处理.
-
但是因为这个requestData()是个异步请求函数,所以我直接去调用这个函数,他并不是立刻马上就返回一些结果给我,然后进行后续的数据处理.
-
所以我传递两个回调函数给他,然后让他执行.
-
存在的缺点:
- 就是不熟悉这个函数的,需要查阅api文档,才能够使用这个函数,很麻烦
- 交互不是很友好
进化-Promise
- 异步函数,返回数据时,返回的数据都是空的.
- 于是出现了回调函数,不要异步函数返回数据了.
- 现在,出现了一个"承诺",异步函数不返回具体的数据了,而是返回一个"承诺"
- 然后我根据这个"承诺"的状态,来决定做哪种处理
function requestData() {
return new Promise((resolve, reject) => {
resolve('这是--成功--返回的数据');
// reject('这是--失败--返回的数据');
});
}
const promise = requestData();
promise.then(
(result) => {
console.log(result);
},
(reason) => {
console.log(reason);
}
);
成功的回调
失败的回调
简写形式-Promise
Promise的承诺移交
通过resolve移交_看后面
- 没执行,时因为这个newPromise的状态时Pending状态.
-
执行了,是因为这个新承诺的状态变成Resolved
-
简单总结:
- 执行哪个函数取决于新的承诺
const newPromise = new Promise((resolve, reject) => {
resolve('承诺被移交给我啦');
});
new Promise((resolve, reject) => {
resolve(newPromise);
// reject('这是--失败--返回的数据');
}).then(
(result) => {
console.log(result);
},
(reason) => {
console.log(reason);
}
);
通过reject移交_注定失败
- 通过reject移交的承诺,无论后边的承诺怎么变化,最后的结果是都时是失败的承诺
const newPromise = new Promise((resolve, reject) => {
resolve('承诺被移交给我啦');
// reject('承诺被移交给我啦,但是没有兑现');
});
new Promise((resolve, reject) => {
// resolve(newPromise);
reject(newPromise);
}).then(
(result) => {
console.log('result:↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓');
console.log(result);
},
(reason) => {
console.log('reason:↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓');
console.log(reason);
}
);
通过then方法移交_看后面
- 前面的都是传入一个Promsie来进行承诺移交
- 其实也是可以传入一个包含then方法的对象,来进行状态移交
- 那么这个"承诺"的状态则取决于这个then方法里面的成功或失败
const obj = {
then: function (resolve, reject) {
// resolve('这个then方法中的成功承诺');
reject('这个then方法中的失败承诺');
},
};
new Promise((resolve, reject) => {
resolve(obj);
// reject(obj);
}).then(
(result) => {
console.log('result:↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓');
console.log(result);
},
(reason) => {
console.log('reason:↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓');
console.log(reason);
}
);
输出效果
Promise中的立即执行和延后执行
立即执行
- 传入Promise()括号的函数都是立即执行的
延后执行
- Promise().then()后面的then里面传入的函数不是立即执行,要等待"承诺"的状态
Promise的多次调用
- 同一个Promise对象,调用多次then方法,则每个then方法都会执行一次
Promise中then方法的链式调用↓↓↓↓↓↓↓↓
then方法的返回值
- 如果你返回的是一个普通的对象,比如字符串,数字,对象等等,系统会自动将其转换成一个Promise,然后这个普通的对象作为resolve()的参数
- 当然你也可以直接返回一个Promise对象,上面可以认为是一种语法糖形式
- 其次就是要区分,Promise的多次调用和链式调用
- 多次调用:同一个Promise对象,多次调用then方法
- 链式调用:原来的Promise对象,只调用一次then方法,后面的then方法,是由前面的then方法产生的新的Promise对象来调用的.
Promise中的的catch方法
- 可以捕获前面的then方法中新生成的promise的"失败承诺"
- 也可以捕获原始的Promise对象的"失败承诺"
- 也就是说,创建一个Promise对象之后,然后采用链式调用then()方法,不论调用多少次,这个catch方法都会从第一个承诺开始捕获"失败的承诺",如果其中有一个"失败承诺",就是会捕获到
类方法Promise.resolve()
传入一个普通对象
- 可以将一个普通对象转换成promise
- 和使用
new Promise((resolve,reject)=>{ resolve([普通对象])})
的效果是一样的
传入一个Promise对象
成功的Promise
失败的Promise
类方法Promise.reject()
- 即使传入一个成功的承诺,也是跳到catch里面执行,
- 因此,可以把Promise.reject()里面的东西当作字符串来进行处理.
类方法Promise.all()
- Promise.all()要等号前面的三个promise对象都变成fullfilled,再拿到结果
- 在数组里面放上三个promise对象,当然,也可以放上普通对象,这个时候,他会将这个普通对象转换成Promise对象,然后和前面的内容参数,拼接成一个数组
const p1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('1111');
}, 1000);
});
const p2 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('2222');
}, 1000);
});
const p3 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('3333');
}, 1000);
});
Promise.all([p1, p2, p3, '4444']).then((res) => {
console.log('res: ' + res);
});
- 只要其中有一个是reject,那么就是执行catch
const p1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('1111');
}, 1000);
});
const p2 = new Promise((resolve, reject) => {
setTimeout(() => {
// resolve('2222');
reject('2222');
}, 1000);
});
const p3 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('3333');
}, 1000);
});
Promise.all([p1, p2, p3, '4444'])
.then((res) => {
console.log('res: ' + res);
console.log(res);
})
.catch((reason) => {
console.log('resason: ' + reason);
});
类方法Promise.allSettled()
- 这个方法要和Promise.all()区分开来
- Promise.all()是只要遇到一个失败的承诺,就会返回
- Promise.allSettled()不管你其中有没有失败的承诺,等你全部的承诺都是执行完毕,再返回
- 所以Promise.allSettled()中,可以看到所有promise的状态
const p1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('1111');
}, 1000);
});
const p2 = new Promise((resolve, reject) => {
setTimeout(() => {
// resolve('2222');
reject('2222');
}, 1000);
});
const p3 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('3333');
}, 1000);
});
Promise.allSettled([p1, p2, p3, '4444'])
.then((res) => {
console.log(res);
})
.catch((reason) => {
console.log(reason);
});
类方法Promise.race()
- race这个词有比赛,赛跑的意思
- 所以,故名顾名思义,前面三个promise对象,谁先完成,就结束返回
类方法Promise.any()
- 前面三个Promise对象中,至少有一个是resolve的,就会fullfilled
- 如果前面三个Promise对象,全部都是reject,最终才会rejected