基于回调函数的异步编程

本文详细介绍了JavaScript中的回调函数,包括其概念、传递参数的方式以及在异步编程中的应用。通过示例展示了回调函数如何解决异步操作的问题,同时也提到了回调地狱的问题。此外,还探讨了Promise作为解决回调地狱的方案,介绍了Promise的基本语法、链式调用、并发操作以及异步函数的概念,旨在帮助读者更好地理解和应用JavaScript的异步编程技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 什么是回调函数
回调函数是指通过函数参数的方式将一个函数传递到另一个函数中,参数函数就是回调函数。
function A () {
console . log ( "A is running" )
}
function B ( callback ) {
console . log ( "B Start" )
callback () // A is running
console . log ( "B End" )
}
B ( A )
我们经常将回调函数写成 callback ,实际上它是 call then back 的简写,含义是调用后返回,就是
在主函数中调用参数函数,参数函数调用完成后返回主函数继续执行主函数中的代码。
为什么在 B 函数中不直接调用 A 函数而要通过参数的方式传递进去 ?
通常在编写应用程序时, B 函数都是语言内部或者其他开发者定义好的,我们看不到内部代码或者
说不能直接在他内部代码中插入我们的代码,而我们又想介入程序的执行,此时就可以通过回调函
数的方式将我们的逻辑传递给 B 函数, B 函数在内部再来调用这个回调函数。
2. 回调函数传递参数
在主函数中调用回调函数时,可以为回调函数传递参数。
function A ( arg ) {
console . log ( "A is running" )
console . log ( arg )
}
function B ( callback ) {
console . log ( "B Start" )
callback ( " 我是 B 函数传递给 A 函数的参数 " ) // A is running
console . log ( "B End" )
}
B ( A )
3. 回调函数在异步编程中的应用
在异步编程中,异步 API 执行的结果就是通过回调函数传递参数的方式传递到上层代码中的。
const fs = require ( "fs" )
fs . readFile ( "./index.html" , "utf-8" , function ( error , data ) {
if ( error ) console . log ( " 发生了错误 " )
console . log ( data )
})
4. 回调地狱
回调地狱是回调函数多层嵌套导致代码难以维护的问题。
基于回调函数的异步编程一不小心就会产生回调地狱的问题。
const fs = require ( "fs" )
fs . readFile ( "./x.txt" , "utf-8" , function ( error , x ) {
fs . readFile ( "./y.txt" , "utf-8" , function ( error , y ) {
fs . readFile ( "./z.txt" , "utf-8" , function ( error , z ) {
console . log ( x )
console . log ( y )
console . log ( z )
})
})
})
const x = fs . readFile ( './x.txt' , 'utf-8' )
const y = fs . readFile ( './y.txt' , 'utf-8' )
const z = fs . readFile ( './z.txt' , 'utf-8' )
console . log ( x )
console . log ( y )
console . log ( z )
4.7 基于 Promise 的异步编程
1. Promise 概述
Promise JavaScript 中异步编程解决方案,可以解决回调函数方案中的回调地狱问题。
可以将 Promise 理解为容器,用于包裹异步 API 的容器,当容器中的异步 API 执行完成后,
Promise 允许我们在容器的外面获取异步 API 的执行结果,从而避免回调函数嵌套。
function A ( arg ) {
console . log ( "A is running" )
console . log ( arg )
}
function B ( callback ) {
console . log ( "B Start" )
callback ( " 我是 B 函数传递给 A 函数的参数 " ) // A is running
console . log ( "B End" )
}
B ( A )
const fs = require ( "fs" )
fs . readFile ( "./index.html" , "utf-8" , function ( error , data ) {
if ( error ) console . log ( " 发生了错误 " )
console . log ( data )
})
const fs = require ( "fs" )
fs . readFile ( "./x.txt" , "utf-8" , function ( error , x ) {
fs . readFile ( "./y.txt" , "utf-8" , function ( error , y ) {
fs . readFile ( "./z.txt" , "utf-8" , function ( error , z ) {
console . log ( x )
console . log ( y )
console . log ( z )
})
})
})
const x = fs . readFile ( './x.txt' , 'utf-8' )
const y = fs . readFile ( './y.txt' , 'utf-8' )
const z = fs . readFile ( './z.txt' , 'utf-8' )
console . log ( x )
console . log ( y )
console . log ( z ) Promise 翻译为承若,表示它承若帮我们做一些事情,既然它承若了它就要去做,做就会有一个过
程,就会有一个结果,结果要么是成功要么是失败。
所以在 Promise 中有三种状态 , 分别为等待 (pending) ,成功 (fulfilled) ,失败 (rejected)
默认状态为等待,等待可以变为成功,等待可以变为失败。
状态一旦更改不可改变,成功不能变回等待,失败不能变回等待,成功不能变成失败,失败不能变
成成功。
2. Promise 基础语法
const fs = require ( "fs" )
const promise = new Promise ( function ( resolve , reject ) {
fs . readFile ( "./x.txt" , "utf-8" , function ( error , data ) {
if ( error ) {
// 将状态从等待变为失败
reject ( error )
} else {
// 将状态从等待变为成功
resolve ( data )
}
})
})
promise
. then ( function ( data ) {
console . log ( data )
})
. catch ( function ( error ) {
console . log ( error )
})
3. Promise 链式调用
const fs = require ( "fs" )
function readFile ( path ) {
return new Promise ( function ( resolve , reject ) {
fs . readFile ( path , "utf-8" , function ( error , data ) {
if ( error ) return reject ( error )
resolve ( data )
})
})
}
readFile ( "./x.txt" )
. then ( function ( x ) {
console . log ( x )
return readFile ( "./y.txt" )
})
. then ( function ( y ) {
console . log ( y )
return readFile ( "./z.txt" )
})
. then ( function ( z ) {
console . log ( z )
})
. catch ( function ( error ) {
console . log ( error )
})
. finally ( function () {
console . log ( "finally" )
})
4. Promise.all 并发异步操作
const fs = require ( "fs" )
Promise . all ([
readFile ( "./x.txt" ),
readFile ( "./y.txt" ),
readFile ( "./z.txt" )
]). then ( function ( data ) {
console . log ( data )
})
4.8 基于异步函数的异步编程
Promise 虽然解决了回调地狱的问题,但是代码看起来仍然不简洁。
使用异步函数简化代码提高异步编程体验。
1. 异步函数概述
const fs = require ( "fs" )
function readFile ( path ) {
return new Promise ( function ( resolve , reject ) {
fs . readFile ( path , "utf-8" , function ( error , data ) {
if ( error ) return reject ( error )
resolve ( data )
})
})
}
async function getFileContent () {
let x = await readFile ( "./x.txt" )
let y = await readFile ( "./y.txt" )
let z = await readFile ( "./z.txt" )
return [ x , y , z ]
}
getFileContent (). then ( console . log )
async 声明异步函数的关键字,异步函数的返回值会被自动填充到 Promise 对象中。
await 关键字后面只能放置返回 Promise 对象的 API
await 关键字可以暂停函数执行,等待 Promise 执行完后返回执行结果。
await 关键字只能出现在异步函数中。
2. util.promisify
Node.js 平台下,所有异步方法使用的都是基于回调函数的异步编程。为了使用异步函数提高异
步编程体验,可以使用 util 模块下面的 promisify 方法将基于回调函数的异步 API 转换成返回
Promise API
const fs = require ( "fs" )
const util = require ( "util" )
const readFile = util . promisify ( fs . readFile )
async function getFileContent () {
let x = await readFile ( "./x.txt" , "utf-8" )
let y = await readFile ( "./y.txt" , "utf-8" )
let z = await readFile ( "./z.txt" , "utf-8" )
return [ x , y , z ]
}
getFileContent (). then ( console . log )
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值