JavaScript的同步编程、异步编程

同步模式

同步模式指的就是我们代码中的任务依次执行,程序执行的顺序与代码的编写顺序一致。

以下代码为同步模式的代码,具体分析其执行顺序

// 首先分析代码结构,本段代码为同步模式,js在读取到代码时,先将一个(anonymous)匿名函数放到
// 调用栈。
console.log('Global begin')

// 在读取到第一行console.log(‘Global begin’)时,将其压到调用栈,随后去执行,当控制台打印出
//结 果后,将其弹出调用栈,继续下一行代码;

// 在读取到bar函数及foo函数时,由于其并未执行,因此调用栈内无执行任务;
function bar() {
    console.log('Bar task')
}

function foo() {
    console.log('Foo task')
    bar()
}

// 在读取到foo()函数调用时,首先将foo()压入调用栈,遇console.log(‘Foo task’)代码,将其压入
// 调用栈,执行完毕后弹出调用栈。随后将bar()压入调用栈,程序去bar()函数内部解析,
// 将console.log(‘Bar task’)压入调用栈。foo()函数执行完毕后,依次将bar()、foo()函数弹出调
// 用栈;

foo()

// 最后将console.log(‘Global end’)压入调用栈并执行,随后将其弹出,代码运行完成,
// 将(anonymous)弹出调用栈,程序完全结束。
console.log('Global end')

输出结果:
  Global begin
  Foo task
  Bar task
  Global end

异步模式

在浏览器端,耗时很长的操作都应该异步执行,避免浏览器失去响应,最好的例子就是Ajax操作。在服务器端,"异步模式"甚至是唯一的模式,因为执行环境是单线程的,如果允许同步执行所有http请求,服务器性能会急剧下降,很快就会失去响应。

异步调用并不会阻止代码的顺序执行,而是在将来的某一个时刻触发设置好的逻辑,所以我们

  • 并不知道逻辑什么时候会被调用
  • 只能定义当触发的时候逻辑是什么
  • 只能等待,同时可以去处理其他的逻辑
// 本段代码为异步模式,js在读取到代码时,先将一个(anonymous)匿名函数放到调用栈。
// 将第一行console.log(‘global begin’)压入调用栈并执行后弹出,此时控制台打印global begin;
console.log('global begin')

// 程序到setTimeout时,首先将setTimeout(timer1)压入调用栈,在web API线程放入timer1计时器,
// 倒计时1.8s,随后将setTimeout(timer1)弹出调用栈;
setTimeout(function timer1() {
    console.log('timer1 invoke')
}, 1800)

// 将setTimeout(timer2)压入调用栈,web API线程放入timer2计时器,倒计时1s,
// 随后将setTimeout(timer2)弹出调用栈;
setTimeout(function timer2() {
    console.log('timer2 invoke')
    setTimeout(function inner() {
        console.log('inner invoke')
    }, 1000)
}, 1000)

// 随后将console.log(‘global end’)压入调用栈并执行后弹出调用栈,代码执行完毕,
// 将anonymous弹出调用栈;
console.log('global end')

// web API将timer1与timer2依次放入事件队列,此时timer2优先倒计时完毕,进入调用栈,
// 然后执行内部代码。将console.log(‘timer2 invoke’)压入调用栈并执行后弹出。
// 随后遇setTimeout(inner),将其压入调用栈并在Web API加入inner计时器,倒计时1s。
// setTimeout(inner)弹出调用栈。
// 此时随倒计时,timer1倒计时完毕,程序进入timer1内部,将console.log(‘timer1 invoke’)压入调用栈并执行后弹出。
// 随后inner()计时器进入任务队列,在倒计时结束后,压入调用栈并执行后弹出。至此,程序执行完毕。

输出结果:
  global begin
  global end
  timer2 invoke
  timer1 invoke
  inner invoke

 回调函数

  • 所有异步编程方案的根基
  • 由调用者定义,交给执行者执行的函数
  • 回调函数指的是需要在将来不确定的某一时刻异步调用的函数。通常,在这种回调函数中,我们经常需要频繁地访问外部数据。
function foo(callback) {
    setTimeout(function () {
        callback()
    }, 3000)
}

foo(function () {
    console.log('这是一个回掉函数')
    console.log('调用者定义这个函数,执行者执行这个函数')
    console.log('起始就是调用者告诉执行者:异步任务结束后应该做什么')
})

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值