nodejs嵌套回调地狱,怎么优化一年了没解决?

我写controller,容易一层一层嵌套,回调里再执行另一个controller

const aa = require("aa")
const bb = require("bb")
const cc = require("cc")

aa(data,  (aaRes)=> {
    bb (aaRes,  (bbRes) =>) {
        cc (bbRes,  (ccRes) =>) {
            res.send({
                code:0,
                msg: "获取成功"
            })
        }
    }
})

怎么优化这种写法?

阅读 4.3k
6 个回答

从 Node 8 开始,Node 提供了 util.promisify()](https://nodejs.org/dist/lates...)) 方法,可以将 callback 形式的 API 封装成 Promise 形式。但如果不是 Node 的标准 callback 形式,还是需要自己写封装(如下示例中的 promisify()

现在框架大多支持 Promise,如果不是非要用原生接口,考虑下 Koa?

参考阅读:

举个例:

function promisify(fn) {
    return function (...args) {
        return new Promise(resolve => {
            fn(...args, resolve);
        });
    };
}

function aa(data, callback) {
    console.log("enter aa", data);
    setTimeout(() => {
        callback("finish aa");
    }, 200);
}

const asyncAa = promisify(aa);
const v = await asyncAa("data");
console.log(v);

http://nodejs.cn/api/util.html#utilpromisifyoriginal

了解下Promise和async/await

把 aa bb cc 改造成返回 promise 的方法,然后使用 async await

const aa = require("aa")
const bb = require("bb")
const cc = require("cc")

async function main() {
    const aaRes = await aa(data)
    const bbRes = await bb(aaRes)
    const ccRes = await cc(bbRes)
    res.send({
        code:0,
        msg: "获取成功"
    })
}

根据函数的性质来写一个promisify,将函数包装成一个promise,这样就可以用async/await

function promisify(fn) {
    return function (data) {
        return new Promise((resolve, reject) => {
            try {
                fn(data, resolve)
            }catch(err) {
                reject(err);
            }
    })
  }
}

function aa(data, cb) {
    setTimeout(() => cb('a data is:' + data))
}

function bb(data, cb) {
    setTimeout(() => cb('b data is:' + data))
}

function cc(data, cb) {
    setTimeout(() => cb('c data is:' + data))
}

(async () => {
     const aaRes = await promisify(aa)('from a;');
     const bbRes = await promisify(bb)('from b;' + aaRes);
    const ccRes = await promisify(cc)('from c;' + bbRes);
    console.log(ccRes);
 })()
推荐问题
宣传栏