如何为 Node.js 编写异步函数
IT技术
javascript
asynchronous
node.js
2021-01-23 05:04:31
6个回答
您似乎将异步 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 来使函数异步。
示例: 非异步函数:
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
在该范围内Promise:
async function ace() {
var r = await new Promise((resolve, reject) => {
resolve(true)
});
console.log(r); // true
}
如果函数不返回Promise,我建议将其包装在您定义的新Promise中,然后解析您想要的数据:
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: ... }
}
底线:利用 Promise 的力量。
试试这个,它适用于节点和浏览器。
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);
});