javascript复习:异步

问题:

  • 同步和异步的区别是什么?
  • 手写用Promise加载一张图片
  • 前端使用异步的场景有哪些?

知识点

  • 单线程和异步
  • 应用场景
  • callback hell 和 Promise

callback hell (回调地狱)

回调函数多层嵌套使用

单线程和异步

  • js 是单线程语言,只能同时做同一件事
  • 浏览器和nodejs 已经支持js启动进程,如 Web Worker
  • js 和 DOM 渲染共用同行一个线程,因为 js 可修改DOM结构
  • 遇到等待(网络请求,定时任务)不能卡住
  • 需要异步
  • 回调callback 函数形式

问题解答:同步和异步的区别是什么

  • 基于js是单线程语言
  • 异步不会阻塞代码执行
  • 同步会阻塞代码执行

    问题解答:手写用Promise加载一张图片

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    function loadImg(src) {
    return new Promise(function (resolve, reject) {
    const imgObj = document.createElement('img');
    imgObj.onload = function () {
    console.log('loaded img success');
    resolve(imgObj);
    };
    imgObj.onerror = function (error) {
    console.log('loaded img error');
    reject(new Error(`图片加载失败${src}`));
    };
    imgObj.src = src;
    });
    }

    问题解答:前端使用异步的场景有哪些

  • 网络请求,如ajax ,图片加载
  • 定时任务,如 setTimeout

补充: 关于promise中reject和catch的问题

一、reject后的东西,一定会进入then中的第二个回调,如果then中没有写第二个回调,则进入catch

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var p1=new Promise((resolve,rej) => {
console.log('没有resolve')
//throw new Error('手动返回错误')
rej('失败了')

})
p1.then(data =>{
console.log('data::',data);
},err=> {
console.log('err::',err)
}).catch(
res => {
console.log('catch data::', res)
})

结果:

1
2
没有resolve
err:: 失败了

then中没有第二个回调的情况

1
2
3
4
5
6
7
8
9
10
11
12
var p1=new Promise((resolve,rej) => {
console.log('没有resolve')
//throw new Error('手动返回错误')
rej('失败了')

})
p1.then(data =>{
console.log('data::',data);
}).catch(
res => {
console.log('catch data::', res)
})

结果:

1
2
没有resolve
catch data:: 失败了

二、resolve的东西,一定会进入then的第一个回调,肯定不会进入catch

1
2
3
4
5
6
7
8
9
10
11
12
13
var p1=new Promise((resolve,rej) => {
console.log('resolve')
//throw new Error('手动返回错误')
resolve('成功了')

})

p1.then(data =>{
console.log('data::',data);
}).catch(
res => {
console.log('catch data::', res)
})

结果:

1
2
resolve
data:: 成功了

不会进入catch的情况,只要resolve了,就算抛出err,也不会进入catch

1
2
3
4
5
6
7
8
9
10
11
var p1=new Promise((resolve,rej) => {
console.log('resolve')
//throw new Error('手动返回错误')
resolve('成功了')

})

p1.catch(
res => {
console.log('catch data::', res)
})

结果:

1
resolve

throw new Error 的情况和rej一样,但是他俩只会有一个发生
另外,网络异常(比如断网),会直接进入catch而不会进入then的第二个回调