Как написать асинхронные функции для Node.js
Я пытался исследовать, как именно писать асинхронные функции. После много вспашки через много документации, мне все еще не ясно.
Как написать асинхронные функции для Node? Как я должен правильно выполнять обработку событий ошибок?
Еще один способ задать вопрос: как интерпретировать следующую функцию?
var async_function = function(val, callback){
process.nextTick(function(){
callback(val);
});
};
Кроме того, я нашел этот вопрос в SO ( "Как создать неблокирующую асинхронную функцию в node.js?" ) интересно. Я не чувствую, что на него еще ответил.
Ответы
Ответ 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");
Этот будет полностью асинхронным.
Это должно быть хорошо, будет написано до завершения асинхронизации.
Ответ 3
Вы должны посмотреть это: Node Tuts episode 19 - Асинхронные шаблоны итерации
Он должен ответить на ваши вопросы.
Ответ 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 также работу.