搞定callback-hell(回调地狱)、promise与async await

1,562 阅读1分钟

关于callback-hell的实现

首先建立一文件夹,目录结构如下:

在files文件夹下建立三个json文件,代码分别如下:

// a.json
{
    "next": "b.json",
    "msg": "this is a"
}

//b.json
{
    "next": "c.json",
    "msg": "this is b"
}
//c.json
{
    "next": null,
    "msg": "this is c"
}

index.js 文件使用node.js实现回调地狱

//nodejs 原生模块读取文件,模仿标准 POSIX 函数的方式与文件系统进行交互。
const fs = require('fs') 
//path 模块提供用于处理文件路径和目录路径
const path = require('path')

// callback 方式获取一个文件的内容
function getFileContent(fileName, callback) {
    const fullFileName = path.resolve(__dirname, 'files', fileName)
    fs.readFile(fullFileName, (err, data) => {
        if (err) {
            console.error(err)
            return
        }
        callback(
            JSON.parse(data.toString())
        )
    })
}

// 测试 callback-hell 也就是著名的回调地狱
getFileContent('a.json', aData => {
    console.log('a data', aData)
    getFileContent(aData.next, bData => {
        console.log('b data', bData)
        getFileContent(bData.next, cData => {
            console.log('c data', cData)
        })
    })
})

输出结果:

上面就是臭名昭著的回调地狱,设想在业务复杂的场景下,上面这种方式回很头疼,所以,为了解决回调地狱promise应运而生,当然包括其他方式(

1、保持简短的代码风格,尽量使用命名函数,避免使用匿名函数
2、模块化,拆分每一个独立的功能函数,封装、打包成一个单独的js文件,通过import导入 3、es6 -- promise
4、es7--async/await

promise改进回调地狱

// 用 promise 获取文件内容,防止callback-hell
function getFileContent(fileName) {
    const promise = new Promise((resolve, reject) => {
        const fullFileName = path.resolve(__dirname, 'files', fileName)
        fs.readFile(fullFileName, (err, data) => {
            if (err) {
                reject(err)
                return
            }
            resolve(
                JSON.parse(data.toString())
            )
        })
    })
    return promise
}

getFileContent('a.json').then(aData => {
    console.log('a data', aData)
    return getFileContent(aData.next)
}).then(bData => {
    console.log('b data', bData)
    return getFileContent(bData.next)
}).then(cData => {
    console.log('c data', cData)
})

输出结果:

  • 相比之下,promise有这很好的优势: 层级更少、逻辑更为清晰等