当函数通常不需要任何参数时,试图理解 node.js 回调?

Trying to understand node.js callback when the function normally doesn't expect any parameters?

我正在尝试使用 node.js 和 node-java 并试图让我的头脑围绕一些概念,特别是如何编写异步方法调用。

我认为,对于 Java 中的函数,myclass.x():

[在 Java] 中:

Z = myclass.x(abc);

并且:

[在节点中。js/node-java]:

myclass.x(abc, function(err,data) {
//TODO
Z = data;});

换句话说,myclass.x 函数使用参数 abc 进行计算,如果没有错误,则结果进入 "data",然后分配给 Z。

对吗?

这是我感到困惑的事情(或其中之一)。

如果函数 myclass.x() 不接受任何参数会怎样?

换句话说,它通常(在Java中)就像这样被调用:

Z = myclass.x();

如果是这样,node.js 代码应该怎样看?

myclass.x(, function(err,data) {
//TODO
Z = data;});

似乎不​​对,但是:

myclass.x( function(err,data) {
//TODO
Z = data;});

似乎也不正确。

那么在这种情况下编写 node.js 代码的正确方法是什么?

提前致谢!!

吉姆

编辑 1:根据评论,我正在添加我正在使用的特定代码是来自另一个问题的最后几行注释掉的行:

node.js and node-java: What is equivalent node.js code for this java code?

这些是行(在另一个问题中注释掉):

var MyFactoryImplClass = java.import("oracle.security.jps.openaz.pep.PepRequestFactoryImpl.PepRequestFactoryImpl");

var result = myFactoryImplClass.newPepRequest(newSubject, requestACTIONString ,requestRESOURCEString , envBuilt)

我试图让最后一行使用异步调用:

MyFactoryImplClass.getPepRequestFactory( function(err,data) {
    //TODO
    pepReqF1=data;})
javaLangSystem.out.printlnSync("Finished doing MyFactoryImplClass.getPepRequestFactory() and stored it in pepReqF1 =[" + pepReqF1 + "]");

但输出显示 pepReqF1 的值为 "undefined"。

如果用一个参数和一个回调调用方法是:

myclass.x(abc, function(err, data) {
  // ...
});

那么调用一个只有回调的方法就是:

myclass.x(function(err, data) {
  // ...
});

function(err, data) { }部分和abc一样只是一个普通参数。事实上,您可以传递一个命名函数:

function namedFun(err, data) {
  // ...
}
myclass.x(abc, namedFun);

甚至:

var namedFun = function (err, data) {
  // ...
}
myclass.x(abc, namedFun);

JavaScript 中的函数是 first-class 对象,例如字符串或数组。您可以将命名函数作为参数传递给其他函数:

function fun1(f) {
  return f(10);
}
function fun2(x) {
  return x*x;
}
fun1(fun2);

就像你可以传递命名数组一样:

function fun3(a) {
  return a[0]
}
var array = [1, 2, 3];
fun3(array);

并且你可以传递一个匿名函数作为参数:

function fun1(f) {
  return f(10);
}
fun1(function (x) {
  return x*x;
});

就像你可以传递一个匿名数组一样:

function fun3(a) {
  return a[0]
}
fun3([1, 2, 3]);

还有一个很好的快捷方式,这样就可以代替:

fun1(function (x) {
  return x*x;
});

你可以这样写:

fun1(x => x*x);

正在将我的评论变成答案...

如果您遇到的问题是 Z 在检查时没有您想要的值,那么这可能是因为时间问题。异步回调会在未来的某个未知时间发生,而您的其余代码将继续 运行。因此,唯一可以可靠地使用传递给异步回调的结果的地方是在回调本身内部,或者在您从该函数调用的某个函数中,并将值传递给它。

因此,如果您的 .x() 方法异步调用它的回调,那么:

var Z;
myclass.x( function(err,data) {
    // use the err and data arguments here inside the callback
    Z = data;
});

console.log(Z);    // outputs undefined

// you can't access Z here.  Even when assigned 
// to higher scoped variables because the callback has not yet
// been called when this code executes

你可以通过理解顺序更清楚地看到这一点

console.log('A');
someAsyncFucntion(function() {
    console.log('B');
})
console.log('C');

这将产生一个日志:

A
C
B

向您展示异步回调会在未来某个时间发生,在您的其余顺序代码已执行之后。


另一方面,

Java 主要使用阻塞 I/O(该函数不会 return,直到 I/O 操作完成),所以您不需要通常不会有这种异步行为,这是 node.js 中的标准做法。注意:我相信 Java 中有一些异步功能,但这不是典型的完成方式,而在 node.js 中,这是典型的完成方式。

如果您尝试从另一个环境移植使用 I/O 的代码,这会造成架构不匹配,因为必须重做结构才能在 [=35= 中正常工作]环境。