Каковы обычные практики, позволяющие избежать ада обратного вызова в Node.JS при использовании асинхронных функций с возвратом ошибок? - PullRequest
0 голосов
/ 11 сентября 2018

Я новичок в Node и сейчас пытаюсь попрактиковаться в чистом скрипте Node без сторонних пакетов npm.Первая проблема, с которой я столкнулся, это то, что мой код начал выглядеть как знак > .Я имею в виду, что у меня был обратный вызов внутри обратного вызова внутри обратного вызова и так далее ... Примерно так:

fs.open(‘filename.json’, 'wx', (error, fileDescriptor) => {
  if (!error && fileDescriptor) {
    // Do something with the file here ...
    fs.writeFile(fileDescriptor, newData, (error) => {
      if (!error) {
        fs.close(fileDescriptor, (error) => {
          if (!error) {
            callback(false);
          } else {
            callback('Error closing the file');
          }
        });
      } else {
        callback('Error writing to new file');
      }
    });
  } else {
    callback('Could not create new file, it may already exists');
  }
});

Это простой пример, но у нас может быть гораздо более сложная логика, которая может включать в себя более асинхронные шаги и, следовательно, более глубокий уровень обратных вызовов.Хотя в приведенном выше примере я использовал модуль fs, квест все еще более общий.Мы можем попасть в ситуацию обратного вызова при использовании других модулей (например, zlib.gzip(str, callback)).

Поэтому мой вопрос Есть ли у нас какие-либо общие практики, позволяющие избежать этого кода обратного вызова внутри обратного вызова и заставить его выглядетьболее прямолинейным и читаемым и в то же время сохраняющим его асинхронным?

Я полагаю, что можно разбить код на более детализированные модули и не иметь многоуровневой асинхронной логики вто же самое место.Я также предполагаю, что есть некоторые пакеты, такие как async , которые могут помочь с этим.Но все же есть ли общие языковые практики / структуры, чтобы сделать такой код обратного вызова внутри обратного вызова более плоским без использования внешних помощников?

Ответы [ 2 ]

0 голосов
/ 20 сентября 2018

Одним из способов предотвращения ситуации с обратным вызовом внутри коллизии является (как это было упомянуто в ветке комментариев) использование операторов Promises и async / await.Это сделает асинхронную структуру кода намного более плоской.Для этого может быть использована удобная функция util.promisify (оригинал) .Это позволяет нам переключаться с обратных вызовов на обещания.Взгляните на пример с функциями fs ниже:

// Dependencies.
const util = require('util');
const fs = require('fs');

// Promisify "error-back" functions.
const fsOpen = util.promisify(fs.open);
const fsWrite = util.promisify(fs.writeFile);
const fsClose = util.promisify(fs.close);

// Now we may create 'async' function with 'await's.
async function doSomethingWithFile(fileName) {
  const fileDescriptor = await fsOpen(fileName, 'wx');
  
  // Do something with the file here...
  
  await fsWrite(fileDescriptor, newData);
  await fsClose(fileDescriptor);
}
0 голосов
/ 12 сентября 2018

Обратные вызовы, в частности, были рассмотрены в комментариях с использованием обещаний.

Другая ваша проблема связана не столько с обратными вызовами, сколько с инвертированными условными блоками.Попробуйте перевернуть свои if блоки.Как то так ...

fs.open('filename.json', 'wx', (error, fileDescriptor) => {
  if (error) {
    return callback(error);
  }

  // Do something with the file
  fs.writeFile(fileDescriptor, newData, (error) => {
    if (error) {
      return callback(error);
    }

    fs.close(fileDescriptor, (error) => {
      //  etc...
    });
  });

});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...