-2

假设我有一个同步功能,例如:

var sum = function(x,y){
  return x+y
}

我想异步调用这个函数。这怎么可能?下面的函数是否被视为异步函数?如果这是一个异步函数,那么我应该在第一个函数之前记录第二个函数的日志吗?我知道这是一个非常简单的例子,它可能不是异步函数的理想情况。但我只是想弄清楚这个基本原理。

function(a, b, c, d, e, f, function(){
  console.log(result);
})
{
   result = sum(a, b);
   result = sum(result, c);
   result = sum(result, d);
   result = sum(result, e);
   result = sum(result, f);
   return
)};


function(a, b, function(){
  console.log(result);
})
{
   result = sum(a, b);
   return
)};

请帮我。如果这不正确,那么请帮助我了解应该如何编写?

4

4 回答 4

3

根据您对昆汀回答的评论

如何创建一个内部有一些操作的函数,这是一个正常的同步函数,但整个流程不等待这个函数完成而是移动到下一个函数。

JavaScript 这种语言没有做到这一点的功能。因此,您查看它运行的环境以查看该环境是否具有该功能。

NodeJS 可以。事实上,它有几个:(setTimeout这有点像浏览器给你的)setImmediate、 和process.nextTick. 对于您的用例,setImmediate可能是最佳选择,但请参阅此问题及其答案以了解更多信息setImmediate看起来像这样:

setImmediate(functionToCall);

(这是一个全球性的,你不必做require任何事情。)

这正是您的标题所要求的:对同步函数的异步调用。


从您下面的评论中:

我只需要创建一个异步函数,在其中我调用一个普通的同步函数。当我的意思是异步函数时,我的意思是当我调用这个函数时,它不会阻碍流程,流程会转到下一个函数,这个函数可以在完成后做一些事情(比如记录)

这与您的问题所问的不太一样。:-)

首先,没有异步函数(在 JavaScript 中)。当您在 JavaScript 中调用函数时,该函数将同步执行。所以这意味着你有两个选择:

  1. 调用代码可以setImmediate用来告诉 Node 异步调用函数,或者

  2. 该函数可以自己执行此操作,可能使用嵌套函数。

这是#1:

function foo() {
    console.log("A");
    setImmediate(bar);
    console.log("B");
}
function bar() {
    console.log("C");
}
foo();

输出:

一种
乙
C

这是#2:

function foo() {
    console.log("A");
    bar("C");
    console.log("B");
}
function bar(arg) {

    setImmediate(run);

    function run() {
        console.log(arg);
    }
}
foo();

...也输出

一种
乙
C

请注意“C”是如何作为参数传递给bar. bar除了将回调调度到它的嵌套函数之外什么都不做runrun使用论据。

于 2013-07-14T14:28:42.160 回答
0

这怎么可能?

它不是。它所做的一切都是同步操作。

在处理本质上是异步的事物时,您使用异步代码。这在 JS 中几乎完全受限于事件处理。

下面的函数是否被视为异步函数?

不,它有一个回调,但它所做的一切都是同步的。

于 2013-07-14T14:13:12.823 回答
0

我不完全确定我了解您的需求,但我相信您正在寻找的是创建并发函数调用,这意味着您可能需要运行潜在的计算密集型代码,而您不想要它在此计算运行时阻止其他代码执行。 Node.js通常用于单线程进程,这意味着在给定时间只能运行一段代码,但仍有一些方法可以做到。

正如@TJ Crowder 的回答中所述,一种方法是将您的函数调用与process.nextTick一起排队,以便它在事件循环的下一个周期运行。这可以帮助将密集计算分解为迭代,并且每次迭代都将排队等待在最后一个事件循环之后的下一个事件循环中运行。这在某些情况下会有所帮助,但并非总是可以将计算分解为彼此异步运行的迭代。如果您正在寻找有关 Javascript 如何异步运行的更详细说明,我建议您阅读这本书

至少有两种其他方法(据我所知)可以使用Node.js实现某种并发- 工作者/线程和子进程。简而言之,子进程只是您的主应用程序运行的另一个 Node.js 进程。如果你想这样做,你可以使用Node.js的原生 *child_process* 模块来运行和管理你的子进程。查看官方文档了解更多信息。

第三种方法是以与浏览器中使用 Web Workers 的方式非常相似的方式使用 Workers。Worker 是在与主应用程序不同的操作系统线程中运行的代码片段。对我来说,这似乎是实现并发的最简单方法,尽管有些人会认为这不是最可靠的方法,并且创建子进程更好。

有一个很好的解释工人如何在MDN上工作。要在Node.js中使用 Workers,您需要一个外部模块,例如webworker-threads

这是从您的示例创建的代码示例,其中包含他们文档中的片段:

var Worker = require('webworker-threads').Worker;

var worker = new Worker(function(){
    onmessage = function(event) {
        result = sum(event.data.a, event.data.b);
        result = sum(result, event.data.c);
        result = sum(result, event.data.d);
        result = sum(result, event.data.e);
        result = sum(result, event.data.f);
        postMessage(result);
        self.close();
    };
});
worker.onmessage = function(event) {
    console.log("The result is: " + event.data);
};
worker.postMessage({a: 1, b: 2, c: 3, d: 4, e: 5, f: 6});

// Do some other stuff that will happen while your Worker runs...

尽管如此,大多数人会尽量避免在Node.js中运行并发代码。Javascript 的异步特性使编写简单而简洁的后端代码变得容易,并且通常您希望通过不尝试将并发性引入应用程序来保持这种方式,除非绝对必要。

于 2013-07-14T15:43:46.387 回答
-2

在 Javascript 中(暂时将节点放在一边)应该通过 setTimeout() 调用异步函数。SetTimeout 在等待时不会阻塞脚本执行:

function someThingThatTakesAWhile() { 
    for (var i = 0; i < someVeryLargeNumber; i++) {
        //...
    };
}
setTimeout(function () {
    someThingThatTakesAWhile();
}, 0);

(尚未测试,请原谅拼写错误,&c)

但是,如果您想在节点中执行此操作,我认为这不是您真正想要的。

于 2013-07-14T14:25:56.620 回答