【问题标题】:how to create a custom asynchronous function in node.js如何在 node.js 中创建自定义异步函数
【发布时间】:2015-11-18 18:13:49
【问题描述】:
我正在尝试做类似的事情。
function fun1(){
for(var j=0;j<20;j++)
{
var n = j;
console.log("i= "+n);
}
}
function fun2()
{
console.log("In Callback");
}
fun1();
fun2();
到目前为止它工作正常并按预期输出。
但是,我想异步调用函数fun1() 和fun2(),这意味着fun2() 在fun1() 之前调用,b'coz fun1() 与fun2() 相比需要一些时间才能完成执行。
如何实现呢,Node.js提供了异步功能,是不是已经定义的功能只能异步或者我们可以根据自己的需要来做。
【问题讨论】:
标签:
javascript
jquery
node.js
asynchronous
【解决方案1】:
我试图提供更好的@Dominik Schreiber's answer版本
async function callee() {
return new Promise((resolve, reject) => {
setTimeout(() => resolve('finished!'), 1000);
})
}
async function caller() {
console.log('started!');
console.log(await callee());
}
caller();
【解决方案2】:
在 JavaScript 中有多种方法可以实现这一点(不是特定于节点的,但有一些模块可以让您的生活更轻松):
回调
它们有点像continuations,很遗憾开发人员不得不手动处理它们(编译器过去常常自己这样做)。但它们有效:
function callee(callback) {
setTimeout(function() {
callback(null, 'finished!');
}, 2000);
}
function caller() {
document.write('started!');
callee(function(err, result) {
document.write(result);
});
}
caller();
在节点环境中,用回调的第一个参数指示错误是很常见的(如callback(new Error("something wrong!")))。
承诺
由于嵌套时回调变得丑陋(想象其中 10-20 个,你会搞砸调试这个),promises 的想法出现了。您可能将它们称为来自 java 的Futures。它们是 ES6 内置的,您可以通过 npm i promise 在节点环境中预先使用它们——许多客户端框架(例如 jQuery、AngularJS)都有自己的实现。原来是Q。
var Promise = require('promise');
function callee() {
return new Promise(function(resolve, reject) {
setTimeout(function() {
resolve('finished!');
}, 1000);
});
}
function caller() {
document.write('started!');
callee().then(function(result) {
document.write(result);
});
}
caller();
发电机
ES6 有generators。您可能通过python 认识他们。
它们也提供异步性,因为它们在计算后yield 新值。
我建议阅读Learn ES2015 了解更多信息。
我个人的意见是永远不要使用生成器,因为它们会严重干扰 Promise 并使调试变得非常困难。
异步/等待
ES7 将通过async/await 让生活变得更加轻松。你基本上可以说一个函数将被异步执行并且你想要等待一个结果(一旦你在一个异步函数中)。 ES7 async functions 是一个很好的开始。好像
async function callee() {
return (() => {
return new Promise((resolve, reject) => {
setTimeout(() => resolve('finished!'), 1000);
})
})();
}
async function caller() {
document.write('started!');
document.write(await callee());
}
// the global async wrapper
(async function() {
caller();
})();
【解决方案3】:
您可以使用以下方法向事件队列添加回调
process.nextTick(callback);
不要那样做,这几乎不是你想要的。
JavaScript 是单线程的,因此添加回调仍然会阻止 f2 的调用。
如果您有一个需要很长时间才能运行的函数,请在 child_process 甚至更好的情况下运行它,为它创建一个单独的微服务。