Nodejs 一段 node.js 代码,如何优化防止 callback hell?

发布于 1周前 作者 ionicwang 来自 nodejs/Nestjs

Nodejs 一段 node.js 代码,如何优化防止 callback hell?

users.userExists({
username: username
}, function(err, exists) {
if (err) {
users.close();
console.error(‘Error testing if user exists: ’ + err);
response.error = ‘业务忙,请稍候重试’;
res.status(HttpStatus.INTERNAL_SERVER_ERROR).json(response);
return;
} else if (exists) {
users.close();
response.error = ‘用户名已经存在’;
res.status(HttpStatus.CONFLICT).json(response);
return;
} else {
users.emailExists(profile.email, function(err, exists) {
console.log(profile.email +’ ’ + exists);
if (err) {
users.close();
console.error(‘checking email error’);
response.error = ‘业务忙,请稍候重试’;
res.status(HttpStatus.INTERNAL_SERVER_ERROR).json(response);
return;
} else if (exists) {
users.close();
response.error = ‘邮箱 ’ + profile.email + ’ 已存在’;
res.status(HttpStatus.CONFLICT).json(response);
return;
}
users.createUser(username, password, profile, function(err, uid, hash) {
if (err) {
response.error = ‘生成用户错误’;
console.error('Failed to create user ’ + err);
res.status(HttpStatus.INTERNAL_SERVER_ERROR).json(response);
} else {
response.statusMessage = ‘成功生成用户’;
response.uid = uid;
// best-effort without a callback
res.json(response);

          }
        });
      });
    }
  })


13 回复

用 async + await


你都知道 callback hell 了,为什么不知道 Promise

Promise 模式,还可以加点 ES2015 语法糖会更甜。

这种程度的 hell 还好啦
按照楼主这样子的代码, async await 可能还得配合 tuple 使用…

如果闲的蛋疼的话可以试试 http://fsprojects.github.io/Fable/
最后结果类似这样
F#<br>async {<br> try<br> let! exists = users.userExists({username: username})<br> if exists:<br> res.status(HttpStatus.CONFLICT).json(response);<br> return;<br> try:<br> let! users.emailExists(profile.email)<br> if exists:<br> response.error = '邮箱 ' + profile.email + ' 已存在';<br> res.status(HttpStatus.CONFLICT).json(response);<br> return <br> try:<br> let! (uid, hash) = users.createUser(username, password, profile)<br> response.statusMessage = '成功生成用户';<br> response.uid = uid;<br> res.json(response);<br> except err:<br> response.error = '生成用户错误';<br> console.error('Failed to create user ' + err);<br> res.status(HttpStatus.INTERNAL_SERVER_ERROR).json(response);<br><br> except err:<br> console.error('checking email error');<br> response.error = '业务忙,请稍候重试';<br> res.status(HttpStatus.INTERNAL_SERVER_ERROR).json(response); <br> except err: <br> console.error('Error testing if user exists: ' + err);<br> response.error = '业务忙,请稍候重试'<br> res.status(HttpStatus.INTERNAL_SERVER_ERROR).json(response);<br> finally:<br> users.close()<br>}<br><br>

擦 , 空格都没了

Promise 、 Generator 、 co 、 async+await
总有一款适合你

Promise + Generator + co 看起来优雅点,然而概念让人乱乱的

目前最合适的是 co

在Node.js中,处理异步操作时的回调地狱(callback hell)确实是一个常见的问题。为了优化代码并避免这种情况,你可以使用以下几种方法:

  1. Promises: Promises提供了一种更清晰、更链式的方式来处理异步操作。

    const fs = require('fs').promises;
    
    fs.readFile('file1.txt')
      .then(data1 => {
        return fs.readFile('file2.txt');
      })
      .then(data2 => {
        console.log(data1.toString() + data2.toString());
      })
      .catch(err => {
        console.error(err);
      });
    
  2. async/await: async/await语法基于Promises,使异步代码看起来更像同步代码,更易读、易维护。

    const fs = require('fs').promises;
    
    async function readFiles() {
      try {
        const data1 = await fs.readFile('file1.txt');
        const data2 = await fs.readFile('file2.txt');
        console.log(data1.toString() + data2.toString());
      } catch (err) {
        console.error(err);
      }
    }
    
    readFiles();
    
  3. 使用控制流库: 如async库,它提供了诸如async.seriesasync.parallel等方法来管理异步流程。

    const async = require('async');
    const fs = require('fs');
    
    async.series([
      function(callback) {
        fs.readFile('file1.txt', 'utf8', callback);
      },
      function(callback) {
        fs.readFile('file2.txt', 'utf8', callback);
      }
    ], function(err, results) {
      if (err) throw err;
      console.log(results[0] + results[1]);
    });
    

以上方法都能有效避免callback hell,提高代码的可读性和可维护性。

回到顶部