【发布时间】:2016-02-21 15:17:58
【问题描述】:
我是 node js 中的异步编程的新手,想知道如何将我以前的(同步)编程转换为 node js 中的可读异步编程。尤其是这个例子:
function getDefaultValue1() {
return getDefaultValue1FromDB();
};
function getDefaultValue2() {
return getDefaultValue2FromDB();
};
function doSomething(var optionalValue1, var optionalValue2){
try {
if(optionalValue1===null){
optionalValue1 = getDefaultValue1();
}
if(optionalValue2===null){
optionalValue2 = getDefaultValue2();
}
var resultList = [];
for(var i = 0; i < optionalValue2; i++) {
resultList.push(functionWithDbCall(optionalValue1, i));
}
return doSomeCalculations(resultList);
}catch(var e){
//log exception
return null
}
};
请注意,节点 js 中的所有 DB-Calls 都是异步的(getDefaultValue1FromDB(var callback)、functionWithDbCall(var optionalValue1, var i, var callback))。
我的想法是: 将回调参数添加到 getDefaultValue => 需要在回调中和 if 之后使用相同的代码。 For 循环在回调被调用之前退出,并且回调需要处理它们被调用的频率并检查以正确的顺序推送项目。将函数更改为使用异步方法需要在调用它的任何地方更改代码,例如将 getDefaultValue 从返回 const int 更改为 DB 调用。
我被困在这里,我发现在为某些库或不可读代码做广告的地方比 asm 或 regex 更糟糕(只写一次,再也不会读/触摸)。我是否错过了我的 node js 学习资料中的一些基本内容,或者这是该语言的设计失败?
所以我希望有人可以告诉我如何用异步节点js编写这个简单的可读函数。
【问题讨论】:
-
异步代码一点也不难读。你只是不习惯而已。自 1999 年以来,我一直在用 Tcl 编写异步代码,所以当 ajax 出现时,我想:嘿,这很熟悉!当 node.js 出现时也发生了同样的事情,我想:嘿,这就像在浏览器中编码!您不习惯的代码/设计模式在开始时总是显得很难/不可读。如果你去 PICLIST 论坛,你会发现那些因为 for 循环和 if/else 令人困惑而不会接触 C 的人——他们只在汇编中编程。
-
问题是,异步代码很快。这就是使 javascript 快速的原因,它在 Python 中很快,在 C 中甚至更快(我以前的工作是在诺基亚维护用 C 编写的数据库代码,使用异步 I/O 以获得电信公司期望从电话目录中获得的吞吐量)。如果您拒绝习惯异步代码,您将永远无法利用它的优势。另一方面,一旦你得到它,你就可以用任何语言编写异步代码。 Javascript 只会使异步代码具有高度可读性。尝试使用在 C 中的 while 循环中实现为 switch-case 语句的状态机来实现它,它会更加混乱。
-
@slebetman 我习惯于使用 pthreads et alii 进行异步编程,使用多线程和互斥锁,每个程序执行 1-10 次。在节点 js 中,每个函数执行 1-10 次。像 if(x){A()};B(); 这样的代码变为 if(x){A(B)};B(); (重复 B)和 for 循环中的有序异步之类的东西真的让我大吃一惊。它完全颠倒了代码流、思考和可读性(你突然每个 for 循环有 5 行样板代码。即使 asm 也有简单的代码流。很好,我使用了通常用 C 语言编程的 XC866,只有 asm 中的中断表,但只有 256字节 RAM ;)
-
因为想学对,所以问别人怎么做,而不是一直做错。
-
多线程编程和异步编程不一样。异步编程几乎 100% 的时间都是单线程的(有一些例外,比如 node.js 磁盘 I/O)。在大学里我学会了:线程和
select()。那当然是在 C 语言中——当时 js 还没有出现在我们的集体雷达上。
标签: javascript node.js asynchronous