JS学习
一、异步顺序
同步任务->微任务->宏任务
<script>
"use strict";
let promise=new Promise((resolve,reject)=>{
setTimeout(()=>{
console.log("settimeout");
resolve("成功");
//reject("失败");
},0);
console.log("promise");
}).then(
value=>{
console.log(value);
},
reason=>{
console.log(reason);
}
);
console.log("baidu.com");
</script>
输出:
promise
baidu.com
settimeout
成功
微任务只有在Promise状态改变时才会创建:
resolve(“成功”);会创建value
reject(“失败”);会创建reason
而且Promise状态只能被改变一次,resolve(“成功”);后,reject(“失败”);无效;
同样,如果先reject(“失败”);,resolve(“成功”);也会失效
二、Promise.then也是一个Promise
<script>
"use strict";
let a=new Promise((resolve,reject)=>{
reject("失败");
console.log("a");
});
let b=a.then(
value=>{
console.log(value);
console.log("b1");
},
reason=>{
console.log(reason);
console.log("b2");
}
);
console.log(a);
console.log(b);
setTimeout(()=>{
console.log(a);
console.log(b);
},0);
</script>
输出:
a
Promise {<rejected>: "失败"}
Promise {<pending>}
成功
b1
Promise {<rejected>: "失败"}
Promise {<fulfilled>: undefined}
可以看到是按顺序执行的同步任务:先是执行Promise里面的操作,然后再执行两个console.log;此时b还没执行,默认状态是pending(准备中)
再执行微任务:then里面的操作,输出前面Promise里面的状态“失败”;
此时then里面的微任务已经执行,因此在最后执行宏任务里面打印b的时候,可以看到b的状态是fulfilled(成功)。
then里面的默认状态是fulfilled,修改了Promise里面的状态不会影响到then。
then是对上个Promise状态改变的处理。
三、then的返回值处理
1、可以返回一个新的Promise,来让后面的then继续执行
<script>
"use strict";
let a=new Promise((resolve,reject)=>{
reject("失败");
console.log("a");
}).then(
value=>{
console.log("b.value:",value);
},
reason=>{
console.log("b.reason:",reason);
return new Promise((resolve,reject)=>{
resolve("解决了");
});
}
).then(
value=>{
console.log("c.value:",value);
},
reason=>{
console.log("c.reason:",reason);
}
);
</script>
输出:
a
b.reason: 失败
c.value: 解决了
如果不返回Promise对象的话,
输出为:
a
b.reason: 失败
c.value: undefined
2、返回有then的对象,自动封装成Promise
用{}包装then:
return {
then(resolve,reject){
resolve("解决了");
}
};
返回一个有then方法的对象:
class RE{
then(resolve,reject){
resolve("解决了");
}
}
return new RE();
返回一个有静态then方法的类:
return class RE{
static then(resolve,reject){
resolve("解决了");
}
};
这些方法都可以~
四、错误监测
1、reject(“失败”);
2、reject();自定义:
使用Error:
reject(new Error("promise fail"));
处理错误:
reason=>{
console.log("c.reason:",reason);
}
输出1:
b.reason: Error: promise fail
还可以只输出错误信息:
console.log("b.reason:",reason.message);
输出2:
b.reason: promise fail
3、使用throw直接抛出错误(只能在同步任务中抛出):
throw(new Error("fail"));
输出错误信息:
b.reason: fail
4、代码错误
例如:使用未声明的变量:
arr++;
输出:
b.reason: arr is not defined
而不是直接红字
5、使用catch处理错误
<script>
"use strict";
let a=new Promise((resolve,reject)=>{
arr++;
console.log("a");
}
).then(
value=>{
console.log("b.value:",value);
}
).catch(
error=>{
console.log("error:",error);
}
);
</script>
输出:
c.value: ReferenceError: arr is not defined
catch可以处理前面的错误,如果错误发生在catch之后,catch无法处理。因此一般将catch放在最后。
而且,如果相对某个任务单独进行错误处理,也可以在其对应的then中单独写reject函数,此时错误就会被reject函数处理,而不是写在最后面的catch。