使用节点 - 6.0。
执行以下操作function A(callback) {
console.log('A');
callback();
}
function B() {
console.log('B')
}
function C() {
console.log('C');
}
A(C);
B();
// Result is A,C,B i expected that A, B, C
但是改变上面的例子以使用process.nextTick()打印A,B,C
function A(callback) {
console.log('A');
process.nextTick(() => {
callback();
});
}
function B() {
console.log('B')
}
function C() {
console.log('C');
}
A(C);
B();
这就是我们所说的zalgo
吗?任何人都可以为我提供一个实时的例子,这将导致重大故障吗?
答案 0 :(得分:2)
不,这些都不是zalgo。您的第一个A
函数始终同步调用其回调函数,并应记录为此类函数。您的第二个A
函数始终异步调用其回调,并应记录为此类。没有什么不对的,我们每天都会使用上千种。输出A C B
和A B C
是 deterministic 。
Zalgo指的是不确定性回调是否异步。
function A(callback) {
console.log('A');
if (Math.random() < 0.5) {
callback();
} else {
process.nextTick(callback);
}
}
调用A(C); B();
的输出完全不可预测。
答案 1 :(得分:1)
首先让我解释代码的工作原理 - 请参阅我添加的代码中的注释:
// first you define function A and nothing happens:
function A(callback) {
console.log('A');
callback();
}
// then you define function B and nothing happens:
function B() {
console.log('B')
}
// then you define function C and nothing happens:
function C() {
console.log('C');
}
// now you call function A with argument C:
A(C);
// when A runs it prints 'A' and calls C before it returns
// now the C runs, prints C and returns - back to A
// A now has nothing more to do and returns
// Now the execution continues and B can be run:
B();
// B runs and prints 'B'
这与Java,C等语言完全相同。
现在,第二个例子:
// first you define function A and nothing happens:
function A(callback) {
console.log('A');
process.nextTick(() => {
callback();
});
}
// then you define function B and nothing happens:
function B() {
console.log('B')
}
// then you define function C and nothing happens:
function C() {
console.log('C');
}
// Then you run A with C passed as an argument:
A(C);
// A prints 'A' and schedules running an anonymous function:
// () => { callback(); }
// on the next tick of the event loop, before I/O events are handled
// but after the current code stack is unrolled
// then it returns
// And then B is run:
B();
// B prints 'B' and returns
// Now nothing else is left to do so the next tick of the event loop starts
// There's one function to run, scheduled earlier so it runs.
// This function runs the `callback()` which was `C`
// so C starts, prints 'C' and returns
// The anonymous function has nothing else to do and returns
// There is no more things on the event loop so the program exits
感谢Bergi在他的回答中解释了什么是Zalgo。现在我更了解你的担忧。
这就是我们所说的zalgo吗?任何人都可以为我提供一个实时的例子,这将导致重大故障吗?
我看过很多像这样的代码:
function x(argument, callback) {
if (!argument) {
return callback(new Error('Bad argument'));
}
runSomeAsyncFunction(argument, (error, result) => {
if (error) {
return callback(new Error('Error in async function'));
}
callback({data: result});
});
}
现在,如果有错误的参数,或者x()
返回后,回调可以在x()
返回之前立即运行。这段代码很常见。为了测试参数,我们可以争辩说它应该抛出一个异常,但让我们暂时忽略它,可能会有一些更好的操作错误例子立即知道 - 这只是一个简单的例子。
现在,如果是这样写的:
function x(argument, callback) {
if (!argument) {
return process.nextTick(callback, new Error('Bad argument'));
}
runSomeAsyncFunction(argument, (error, result) => {
if (error) {
return callback(new Error('Error in async function'));
}
callback({data: result});
});
}
可以保证在x()
返回之前永远不会调用回调。
现在,如果这可能导致&#34;重大故障&#34;完全取决于它的使用方式。如果你运行这样的东西:
let a;
x('arg', (err, result) => {
// assume that 'a' has a value
console.log(a.value);
});
// assign a value to 'a' here:
a = {value: 10};
然后它有时会因x()
的版本process.nextTick
而崩溃,并且永远不会因x()
版process.nextTick()
而崩溃。