js 从同步到异步,从callback 到promise
以一个简单的函数来说明
同步代码函数调用
function add (a, b) {
let c = a + b
return c
}
// 调用方式
let c = add(1, 2)
// 拿到c , 做一些事情
同步代码,配和js 的单线程,自上而下执行
异步代码 – 回调函数
function add (a, b, callback) {
let c = a + b
// ... 省略中间代码
// 调用 callback
callback(err, c)
}
// 调用方式
// 回调函数的第一个参数默认为错误,第二个为调用函数返回的值
demo(1, 2, function( err, c ) {
if (err) throw err
// 拿到返回的c 做一些事情
// ...
console.log(c)
})
调用add 函数时,传入的函数并不会同步执行,而是会等待被调用后在执行
异步函数-- Promise
function add (a, b) {
return new Promise(resolve, reject ) {
let c = a + b
resolve (c) // reject(c)
}
}
// 调用
demo(1, 2).then(c => { // catch(() => {})
// 拿到返回结果c
// ...做一些事情
console.log(c)
})
- promise 的写法,有效的降低了回调函数的回调地狱问题
- 注意promise 的调用方式和回调函数有着明显的不同
- resolve 对应then, 表示成功状态; reject 对应catch ,表示失败状态
- 随着代码量的增加,这种promise的方式也会显得很臃肿,进而产生了 async await 语法糖,简化写法
异步代码-- async + await
async function add (a, b) {
let c = a + b
return c
}
// 调用
let c = await add(1, 2)
//拿到c , 做一些事情
- 这种写法和第一种的同步代码简直一摸一样,只是多了两个关键字来修饰,不得不说写起来是十分方便,
- async 表示 该函数会返回一个promise, 在函数中,使用return 返回的值来表示resolce/reject返回的值(l转了一圈,又回到了同步书写代码的方式)
- await 只能在async 修饰的函数只使用,表示等待之后的异步代码被执行,简化了promsie中的then 和catch 的写法
总结
从同步到callback,promise,再到async+ await, 书写代码的方式从简单变复杂再到简单,但是表达的含义却有着天壤之别,不得不说程序设计的魅力在此表现的淋漓尽致。