携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第16天,点击查看活动详情
前言
大白话说JS内容包括:DOM的一些操作,Promise相关, 微任务宏任务,作用域,变量提升,闭包,变量类型,深浅拷贝,原型和作用域链,后续争取把js重点都记录上,深入浅出。
异步
啥是同步,啥是异步啊,这跟单线程,多线程有啥区别呀?嗯...
- 使用promise加载一张图片
- then,catch改变promise的状态
- async , await , 和Promise
- 微任务和宏任务
使用promise加载一张图片
考验对promise的基本使用情况。思路:实例化一个promise对象,对图片的加载分别成功与否用resolve, reject 处理。
function loadImage (src) {
// 创建并实例化一个promise对象
const promise = new Promise((resolve, reject) => {
const img = document.createElement('img');
// 如果图片加载成功,就传入图片进resolve
img.onload = function () {
resolve(img);
}
img.onerror = function () {
const err = new Error(`图片加载失败, url:${{ src }}`)
reject(err);
}
img.src = src;
});
return promise;
}
const url = 'https://cn.bing.com/th?id=OHR.WalhallaOverlook_ZH-CN1059655401_1920x1080.jpg&rf=LaDigue_1920x1080.jpg'
loadImage(url).then(img => {
console.log('img', img);
}).catch(e => {
console.log('err', e);
})
使用then,catch改变promise的状态
先说结论:
then 和 catch 正常返回的时候,Promise状态是 fulfilled ,抛出错误的时候,Promise 状态是 rejected。 fulfilled 状态的Promise执行then 的回调,而rejected则执行catch的回调。
怎么理解?看下面例子:
const p1 = Promise.resolve();
console.log('p1', p1);
const p1Then = p1.then(() => {
console.log('p1Then', p1Then);
})
const p1Error = p1.then(() => {
throw new Error('p1 then error')
})
console.log('p1Error', p1Error);
p1Then.then(() => {
console.log('fulfilled状态走then回调');
}).catch(() => {
console.log('fulfilled状态走catch回调');
})
p1Error.then(() => {
console.log('p1Error走then回调');
}).catch(() => {
console.log('p1Error走catch回调');
})
首先定义一个 resolve 返回值的promise对象,打印显示状态为 fulfilled ,保存当前信息在打印走catch还是then;然后在手动跑出个错误,打印当前状态,在判断走catch还是then。结果显示:
再回过头看先前的结论,发现也不难理解。reject类型的演示也差不多,结论见上。
async , await , 和Promise
这里也先说这三者的结论: 执行async 函数返回的都是Promise对象;promise.then的情况对应await ;promise.catch异常情况对应try...catch。
// async结论 :async返回的都是Promise对象
async function test1 () {
return 1;
}
const result1 = test1();
console.log('result1', result1);
// await 结论:promise.then成功情况对应await
async function test2 () {
const p2 = Promise.resolve(2);
p2.then(data => {
console.log('promise情况:', data);
})
const data = await p2;
console.log('await情况:', data);
}
test2();
// promise.catch异常情况对应try...catch
async function test3 () {
const p3 = Promise.reject(6);
try {
const data3 = await p3;
console.log('data3', data3);
} catch (e) {
console.log('try-catch捕捉的promise异常:', e);
}
}
test3();
例子比较通俗易懂,配合结果应该能更清晰的理解结论。
微任务和宏任务
JS的一个执行代码机制,采用单线程的事件循环方式管理异步任务,优点简化编程模型,缺点无法发挥CPU的全部性能(但对前端其实没影响)
执行顺序:
- 先执行同步任务
- 微任务:process.nextTick,Promise,Async/Await
- 宏任务:计时器,ajax,读取文件,setTimeout,setInterval
事件循环大致按上述执行顺序执行。值得注意的是,Async/Await就是promise的一种语法糖,有Async没有Await,相当于同步任务,有了Await相当于是promise的then。
console.log('a');
setTimeout(()=>console.log('宏1'), 0);
(async ()=>{
console.log(1);
await console.log(2);//此处相当于.then()处理,将后面的打印放到微任务中,
console.log(3);
setTimeout(()=>console.log('宏2'), 0);
})().then(()=>{
console.log(4);
});
console.log('b');
//a,1,2,5,3,4,宏1,宏2