如何为Node.js编写异步函数
How to write asynchronous functions for Node.js
我试图研究异步函数应该如何准确地编写。在翻阅了大量的文档之后,我还是不太清楚。
如何为Node编写异步函数?我应该如何正确地实现错误事件处理?
问这个问题的另一种方式是:我应该如何解释下面的函数?
var async_function = function(val, callback){
process.nextTick(function(){
callback(val);
});
};
另外,我发现这个问题在SO("我如何在node.js中创建一个非阻塞异步函数?")有趣。我觉得这个问题还没有答案。
您似乎将异步IO与异步函数混淆了。node.js使用异步非阻塞IO,因为非阻塞IO更好。理解它的最好方法是去看一些ryan dahl的视频。
如何为Node编写异步函数?
只是写普通的函数,唯一的区别是它们不是立即执行,而是作为回调传递。
一般来说,API会给你一个回调,第一个参数是err。例如如何正确实现错误事件处理
database.query('something', function(err, result) {
if (err) handle(err);
doSomething(result);
});
是常用的模式。
另一个常见的模式是on('error')
。例如
process.on('uncaughtException', function (err) {
console.log('Caught exception: ' + err);
});
编辑: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
在当前事件循环调用栈为空后触发。在async_function
和console.log(43)
运行之后,该调用堆栈是空的。所以我们输出43后面跟着42。
你应该对事件循环做一些阅读。
仅仅通过回调是不够的。例如,你必须使用settimer来使函数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");
如果你要运行上面的例子,这应该是好的,将不得不等到这些函数将完成工作。
伪多线程(异步)函数: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第19集-异步迭代模式
它应该能回答你的问题。
如果你知道一个函数返回一个promise,我建议使用JavaScript中新的async/await特性。它使语法看起来是同步的,但工作却是异步的。当您将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: ... }
}
底线:利用承诺的力量
试试这个,它对节点和浏览器都有效。
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);
});
我已经为node.js处理了太多的时间。我主要负责前端工作。
我发现这很重要,因为所有的节点方法都异步处理回调,把它转换成Promise处理它会更好。
我只是想展示一个可能的结果,更精简和可读性。使用ECMA-6和async,你可以这样写:
async function getNameFiles (dirname) {
return new Promise((resolve, reject) => {
fs.readdir(dirname, (err, filenames) => {
err !== (undefined || null) ? reject(err) : resolve(filenames)
})
})
}
(undefined || null)
适用于repl(读取事件打印循环)场景,使用undefined也可以。
- 如何在异步函数中使用javascript对象
- Meteor:异步函数回调异常:onAfterAction
- 未调用jquery异步函数
- 使用来自不同异步函数的响应创建一个json对象
- 如何在异步函数中正确使用Promise.all()和then()
- 从异步函数返回值
- 如何按照承诺使用mocha/chai/chai测试ES7异步函数
- 如何在将Node异步函数转换为promise时使用Q库
- 如何在异步函数与Deferredjquery之间同步
- ng用异步函数模拟怪异行为
- 用mocha测试异步函数
- 用于异步函数中的循环和定时问题
- Node.js设计:多个异步函数使用作为闭包传递的函数写入数据库
- 嵌套异步函数未及时返回数据的问题
- 在异步函数中维护变量的状态
- 递归异步函数
- Bluebird promisifyAll不会创建整个异步函数集
- 递归调用异步函数
- 异步函数调用是否可以在两个同步语句之间完成
- 如何在nodejs中实现异步函数