1.回调函数
这一章教你如何做一个时间管理大师!
我们试想一个排队办手续的场景,在轮到你之前,你可以玩手机,可以和朋友聊天,等等。可以做很多很多事情。这样就可以成功的打发这段排队等候的无聊时光,同时做好自己的事情,同时也不影响排队的进程。这样的过程和异步处理 的原理有点相似。
般来说,异步处理常常用于处理那些需要较长时间才能完成的操作,例如从服务器上获取数据、读取文件、进行网络请求等。如果使用同步处理,程序就会一直等待这些操作的完成,造成程序的阻塞。而使用异步处理,则可以充分利用程序的资源,同时处理其他任务。
于是我们便引入了回调函数
setTimeout(function(){
console.log('执行了回调函数');
},3000) //3000毫秒
我们让程序等个3000毫秒,之后自动执行
很好,3000毫秒以后执行就很合适。
但是在项目中,不可能只有一个进程需要处理
setTimeout(function () { //第一层
console.log('清早起来');
setTimeout(function () { //第二程
console.log('真tm的困啊');
setTimeout(function () { //第三层
console.log('腰酸腿疼脖子硬');
.......//好多好多层
}, 1000)
}, 2000)
}, 3000)
这玩意就被称为**回调地狱,**推断个语法累死你
2.Promise
1.then.catch.finally的用法
在ES6中,引入了Promise这个概念,你可以把它类比为一个if-else语句,
执行成功了怎么样,失败了怎么样
下面开始正文:
Promise原本的状态是_pending(初始状态)
当执行成功完成之后,状态从pending变成了fulfilled(已对现),之后我们实行那些操作。
当执行操作失败之后,状态从pending变成了reject(已拒绝)_,之后我们实行那些操作。
我们写一个案例
先翻译下,resolve是解决的意思,reject是拒绝的意思。
var myPromise = new Promise((resolve, reject) => {
// 执行异步操作
if (/* 异步操作成功 */) {
resolve(value); // pending -> fulfilled
} else {
reject(error); // pending -> rejected
}
});
myPromise
.then(value => {
// 成功处理异步操作的结果
})
.catch(error => {
// 处理异步操作失败的情况
})
.finally(() => {
console.log('执行完毕');
});
也就是说,异步操作最终肯定只有两个结果,要么成功要么失败,这个叫Promise的东西,会带着**成功(resolve)或者失败(reject)**的信息一起返回
- 如果带回来的是成功的信息,那就会执行后面程序中then()里面的代码。
- 如果带回来的是失败的信息,那就会执行后面程序中catch()里面的代码。
- 不论是成功还是失败,都会输出finally里面的东西。
当然了,上面的catch也不是必须的,你也可以这么写
var p = new Promise((resolve,reject)=>{
//主动调用reject,并传入实参2
reject(2)
})
// 此时,P的状态是rejected,且值promiseValue 是2.
p.then((res)=>{
// p的状态是resolved
// 所以这句代码不会执行。
console.log("then,ok",res)
},(err)=>{
// p的状态是rejected
// 执行then的第二个参数
// 并把promisevalue传进来。
console.log("then,err",err)
})
2.链式处理
then返回的也是一个_fulfilled/reject值得,就是是否对现_
// 方法
function todo1() {
console.log("一");
}
function todo2() {
console.log("二");
console.log(a); //这里的a没有定义,会报错
}
function todo3() {
console.log("三");
}
function todo4() {
console.log("四");
}
// 执行操作
var p = new Promise((resolve, reject) => {
resolve()
})
// 分别调用方法
p.then(todo1)
.then(todo2)
.then(todo3)
.catch(todo4);
输出结果:一,二,四
流程:
p里面写的是resolve,那直接执行第一个then里面的代码。成功后返回resolve,可以进入第二个then(todo2)。
进入todo2中,console.log(“二”);先执行,但是由于a没有定义(通常情况下要写一个**var a;再写console.log(a);**但是这里没有写)执行失败,返回reject,这样就没法继续执行then,因为then必须要操作成功返回resolve才能进入,既然语句操作失败,那只能进入catch中,执行todo4,todo3不执行,直接输出4。
想要详细了解的朋友,点击这里:Promise
3.async/await
在刚刚提到的链式中,我们发现上面写的简单,但是理解起来超级麻烦,于是我们引入了async/await
这个是方便处理链式的一个语法糖
(语法糖就是原来使用一大串代码才能使用的东西,现在只需要把语法糖丢进去就可以使用,减少代码量)
他的基本写法是这样的
//这一段方法不用看
function fn() {
return new Promise(resolve => {
setTimeout(() => {
resolve('resolved');
}, 2000);
});
}
//看这里!!!
//1.async就是异步函数的一个标志
//2.await就是等待fn()这个函数执行完,执行完成后会返回一个promise值,也就是执行成功resolve或者失败reject
async function asyncCall() {
console.log('calling');
const result = await fn();
console.log(result);
// Expected output: "resolved"
}
1.async就是异步函数的一个标志
2.await就是等待fn()这个函数执行完,执行完成后会返回一个promise值,这个值的内容就是执行成功:resolve或者失败:reject。
好像也看不出来好在哪里,但是要是作用于链式,那就牛了
举个例子
// 使用 async/await 处理异步操作
async function getDataWithAsync() {
try {
// 使用 await 关键字等待 fetch 方法返回的 Response 对象
// 说人话就是看看这个链接请求成功了没
const response = await fetch('https://api.example.com/data');
// 使用 await 关键字等待 Response 对象的 json 方法返回的 Promise 对象
// 说人话就是看看response转化成.json了没
const data = await response.json();
// 如果上面的都成功了(await返回resolve),输出这一句
console.log(data);
} catch (error) {
// 如果上面的await返回的是reject,失败了,就输出这一句
console.error(error);
}
}
// 使用 Promise 处理异步操作
function getDataWithPromise() {
// 使用 fetch 方法发送 HTTP 请求并返回 Promise 对象
fetch('https://api.example.com/data')
// 使用 then 方法注册回调函数处理 Response 对象
.then(response => response.json())
// 使用 then 方法注册回调函数处理 JSON 数据
.then(data => console.log(data))
// 使用 catch 方法捕获错误并输出错误信息
.catch(error => console.error(error));
}
注意,第二段代码里面没有写promise,但是fetch返回的值是promise类型,也就是成功或失败,想要详细了解可以看这里:fetch()