Подтвердить что ты не робот

Как написать асинхронные функции для Node.js

Я пытался исследовать, как именно писать асинхронные функции. После много вспашки через много документации, мне все еще не ясно.

Как написать асинхронные функции для Node? Как я должен правильно выполнять обработку событий ошибок?

Еще один способ задать вопрос: как интерпретировать следующую функцию?

var async_function = function(val, callback){
    process.nextTick(function(){
        callback(val);
    });
};

Кроме того, я нашел этот вопрос в SO ( "Как создать неблокирующую асинхронную функцию в node.js?" ) интересно. Я не чувствую, что на него еще ответил.

4b9b3361

Ответ 1

Кажется, вы запутываете асинхронный IO с асинхронными функциями. node.js использует асинхронный неблокирующий IO, поскольку лучше не блокировать IO. Лучший способ понять это - посмотреть некоторые видео от ryan dahl.

Как написать асинхронные функции для Node?

Просто напишите нормальные функции, единственное отличие состоит в том, что они не выполняются немедленно, а передаются как обратные вызовы.

Как правильно выполнить обработку ошибок ошибок

В общем API дает вам обратный вызов с ошибкой в ​​качестве первого аргумента. Например

database.query('something', function(err, result) {
  if (err) handle(err);
  doSomething(result);
});

Это общий шаблон.

Другим распространенным шаблоном является on('error'). Например

process.on('uncaughtException', function (err) {
  console.log('Caught exception: ' + err);
});

Edit:

var async_function = function(val, callback){
    process.nextTick(function(){
        callback(val);
    });
};

Вышеуказанная функция при вызове

async_function(42, function(val) {
  console.log(val)
});
console.log(43);

Будет выводиться 42 на консоль асинхронно. В частности, process.nextTick срабатывает после того, как текущий столбец eventloop пуст. Этот стек вызовов пуст после запуска async_function и console.log(43). Итак, мы печатаем 43, затем 42.

Вероятно, вы должны сделать некоторые чтения в цикле событий.

Ответ 2

Просто пройти по обратным вызовам недостаточно. Вы должны использовать настройщик, например, для создания функции async.

Примеры: Не асинхронные функции:

function a() {
  var a = 0;    
  for(i=0; i<10000000; i++) {
    a++;
  };
  b();
};

function b() {
  var a = 0;    
  for(i=0; i<10000000; i++) {
    a++;
  };    
  c();
};

function c() {
  for(i=0; i<10000000; i++) {
  };
  console.log("async finished!");
};

a();
console.log("This should be good");

Если вы выполните над примером, это должно быть хорошо, придется ждать, пока эти функции не закончатся, чтобы работать.

Функции многопоточности (async):

function a() {
  setTimeout ( function() {
    var a = 0;  
    for(i=0; i<10000000; i++) {
      a++;
    };
    b();
  }, 0);
};

function b() {
  setTimeout ( function() {
    var a = 0;  
    for(i=0; i<10000000; i++) {
      a++;
    };  
    c();
  }, 0);
};

function c() {
  setTimeout ( function() {
    for(i=0; i<10000000; i++) {
    };
    console.log("async finished!");
  }, 0);
};

a();
console.log("This should be good");

Этот будет полностью асинхронным. Это должно быть хорошо, будет написано до завершения асинхронизации.

Ответ 4

Попробуйте это, он работает как для node, так и для браузера.

isNode = (typeof exports !== 'undefined') &&
(typeof module !== 'undefined') &&
(typeof module.exports !== 'undefined') &&
(typeof navigator === 'undefined' || typeof navigator.appName === 'undefined') ? true : false,
asyncIt = (isNode ? function (func) {
  process.nextTick(function () {
    func();
  });
} : function (func) {
  setTimeout(func, 5);
});

Ответ 5

Если вы ЗНАЕТЕ, что функция возвращает обещание, я предлагаю использовать новые функции async/await в JavaScript. Это делает синтаксис синхронным, но работает асинхронно. Когда вы добавляете ключевое слово async в функцию, это позволяет вам await обещаний в этой области:

async function ace() {
  var r = await new Promise((resolve, reject) => {
    resolve(true)
  });

  console.log(r); // true
}

если функция не возвращает обещание, я рекомендую обернуть ее новым обещанием, которое вы определяете, а затем разрешите нужные данные:

function ajax_call(url, method) {
  return new Promise((resolve, reject) => {
    fetch(url, { method })
    .then(resp => resp.json())
    .then(json => { resolve(json); })
  });
}

async function your_function() {
  var json = await ajax_call('www.api-example.com/some_data', 'GET');
  console.log(json); // { status: 200, data: ... }
}

Итог: используйте силу обещаний.

Ответ 6

У меня слишком много часов для такой задачи для node.js. Я в основном парень-фронтмен.

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

Я просто хочу показать возможный результат, более скудный и читаемый. Используя ECMA-6 с асинхронным режимом, вы можете написать его вот так.

 async function getNameFiles (dirname) {
  return new Promise((resolve, reject) => {
    fs.readdir(dirname, (err, filenames) => {
      err !== (undefined || null) ? reject(err) : resolve(filenames)
    })
  })
}

(undefined || null) используется для сценариев repl (read event print loop), используя undefined также работу.