当前位置: 首页 > 面试题库 >

Node.js:异步回调执行。这是Zalgo吗?

太叔小云
2023-03-14
问题内容

使用 节点-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吗?谁能提供给我一个实时的例子,这将导致重大故障?


问题答案:

首先,让我解释一下代码的工作原理-请参阅添加的代码中的注释:

// 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()返回之前被调用。

现在,这是否可能导致“重大故障”完全取决于其使用方式。如果运行以下命令:

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()



 类似资料:
  • 问题内容: 假设我有这段代码 我想知道的是该函数是否将异步执行。 问题答案: 设完成为Call(执行者,未定义,«resolvingFunctions。[[Resolve]],resolvingFunctions。[[Reject]]»)。 如果完成是突然完成,则 令status为Call(resolvevingFunctions。[[Reject]],undefined,«completion。

  • 问题内容: 我整天都在整理此问题,希望有人能帮助您确定我的问题。我已经使用Ajax在我的应用程序中创建了“异步进度回调”类型的功能。当我将功能剥离到测试应用程序中时,我得到了预期的结果。见下图: 所需功能 当我使用相同的代码将功能绑定到我的单页应用程序中时,出现了一种阻塞问题,其中所有请求仅在最后一个任务完成后才得到响应。在测试应用程序中,所有请求均会依次响应。服务器报告所有请求的状态(“待定”)

  • 问题内容: 我对如何在Mocha测试中包装嵌套的异步回调感到困惑。这是令人讨厌的代码示例:正在调用Amazon S3以检查文件是否存在: 代码挂起等待完成(如果我省略done())-或者,代码完成而没有回调,或者,节点抱怨done()被多次调用。 在下面的帮助下,我可以正常工作了,但看起来像是异步伏都炖菜 问题答案: 尝试使用async.serial。在第一个条目内,使用async.each运行多

  • 问题内容: 我是JavaScript和node.js的新手。我想遍历目录并将所有文件统计信息(而不是其他目录)添加到数组中。如下所示,我的代码存在问题,因为回调可能在for循环完成后被调用,因此在回调方法中使用“ i”变量将不起作用。但是代码应如何显示,以便以下代码段起作用?它与闭包有关吗? 感谢帮助! 问题答案: 您需要使用闭包是正确的。您应该将循环的内容包装在一个自调用函数中,以保留每次迭代的

  • 异步注解@Async,默认情况下是不生效的,需要的话可以启用. 该加载器有一个可选参数,线程池大小,默认是32,详情可以查阅org.nutz.aop.interceptor.async.AsyncAopIocLoader @IocBy( args={"*json","ioc/", "*anno","net.wendal.nutzbook", "*a

  • Node 库以多种方式处理异步功能。最常见的模式是 error-first callbacks,但是你还可能会遇到 streams、promises、event emitters、child processes, 或 observables。gulp 任务(task)规范化了所有这些类型的异步功能。 任务(task)完成通知 当从任务(task)中返回 stream、promise、event e