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


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

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

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

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

и этот вопрос так ("Как создать неблокирующую асинхронную функцию в узле.Джей?") интересный. Я не чувствую, что на него уже ответили.

5 105

5 ответов:

вы, кажется, путаете асинхронный ввод-вывод с асинхронными функциями. узел.Яш использует асинхронного неблокирующего ввода-вывода, поскольку неблокирующее IO-это лучше. Лучший способ понять это-посмотреть некоторые видео Райана Даля.

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

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

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

обычно 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 callstack пуст. Этот стек вызовов пуст после async_function и console.log(43) бежать. Итак, мы печатаем 43, а затем 42.

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

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

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

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");

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

псевдо многопоточные (асинхронные) функции:

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");

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

вы должны посмотреть это: Node Tuts episode 19-асинхронные итерационные Шаблоны

Он должен ответить на ваши вопросы.

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

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);
});

если вы знаете, что функция возвращает обещание, я предлагаю использовать новые функции 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: ... }
}

итог: рычаги сила обещаний.