javascript - Node.js 模块中的异步函数

标签 javascript node.js

我对 JavaScript/Node.js 不太熟悉,所以请耐心等待。而且我的英语可能不太好。

我正在尝试编写一个 Node.js 模块 module.js ,其中包含执行一些长时间运行工作的函数。有点像这样:

var exec = require('child_process').exec;

module.exports.myFunction1 = function(callback) {
    // this function runs for like 3 seconds
    exec('long running shell command' ,function(err,stdout,stderr) {
        callback(stdout);
    })
};

module.exports.myFunction2 = function(callback) {
    // this function runs for like 1 second
    exec('long running shell command' ,function(err,stdout,stderr) {
        callback(stdout);
    })
};

现在,我还有一个 ma​​in.js,我可以在其中调用这些函数:

var module = require('./module.js');

var output1 = module.myFunction1();

var output2 = module.myFunction2();

我的第一个问题是我的函数返回未定义。我知道这是因为 exec 函数异步运行,因此该函数在 exec 完成之前返回。这基本上就是我想要的,但是我如何告诉我的函数它应该只在 exec 完成时回调?

当我在 main.js 中调用这些函数时,我也不希望这些函数阻塞 node.js。所以基本上,我的上述代码的输出将是...

Output myFunction2: Output2
Output myFunction1: Output1

...因为 myFunction2() 比 myFunction1() 完成得更快。

我尝试了很多在网上找到的解决方案,但似乎都无法正常工作。

提前非常感谢您!

--- 编辑 ---

好的,我有一个稍微正确的解决方案。现在我的代码如下所示:

module.js

var Q = require('q');
require('shelljs/global')

module.exports = {
    myFunction1: function () {
        var deferred = Q.defer();

        var result = exec('long running command', {silent:true}).output.toString();

        if (ok) {
            deferred.resolve(result);
        }
        else {
            deferred.reject('Error');
        }

        return deferred.promise;
    },

    myFunction2: function () {
        var deferred = Q.defer();

        var result = exec('long running command', {silent:true}).output.toString();

        if (ok) {
            deferred.resolve(result);
        }
        else {
            deferred.reject('Error');
        }

        return deferred.promise;
    }
}

我的ma​​in.js现在像这样:

var module = require('./module');

module.myFunction1()
    .then(function (result) {
        console.log('Result 1: ' + result);
    })
    .fail(function (error) {
        console.log(error)
});

module.myFunction2()
    .then(function (result) {
        console.log('Result 2: ' + result);
    })
    .fail(function (error) {
        console.log(error)
});

我得到了预期的输出:

Result 1: Output that myFunction1() generated
Result 2: Output that myFunction2() generated

我现在的问题是,myFunction1() 总是在 myFunction2() 之前记录,即使 myFunction2() 先完成也是如此。我对 Promise 的理解有误吗? myFunction2() 完成后不应该立即返回吗?

最佳答案

您的函数需要回调。这些参数是在完成时调用的函数,这使得它很容易做到

var exec = require('child_process').exec;
module.exports.myFunction1 = function(callback) {
    // this function runs for like 3 seconds
    exec('long running shell command' ,function(err,stdout,stderr) {
        callback(stdout);
    })
};

module.myFunction1(function(stdout){
      console.log("Output myFunction1: " + stdout);
});

在您的情况下,使用回调是最简单的解决方案,但您应该意识到还有其他模式可以处理异步执行。这是a good overview 。例如,一个流行的解决方案,当您必须链接异步延续时特别有趣,是使用 promise ,它允许

var exec = require('child_process').exec;
module.exports.myFunction1 = function() {
    return new Promise(function(resolve, fail){
        // this function runs for like 3 seconds
        exec('long running shell command' ,function(err,stdout,stderr) {
            if (err) fail(err);
            else resolve(stdout, stderr);
        });
    });
};

module.myFunction1()
.then(function(stdout){
      console.log("Output myFunction1: " + stdout);
})
.then(module.myFunction2)
.then(function(stdout){
      console.log("Output myFunction2: " + stdout);
})

关于javascript - Node.js 模块中的异步函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34704709/

相关文章:

node.js - 在 Sequelize 中的连接表上添加属性

javascript - OpenAI ChatGPT (GPT-3.5) API 错误 404 : "Request failed with status code 404"

node.js - nodejs fatal error : CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory

javascript - (jQuery) 如何找到具有特定类的第一个链接?

storage - Nodejs 内存存储

javascript - 将 "map"与 Promise 结合使用会返回有序和无序结果

Javascript - 替换字符串子字符串内的字符

javascript - 将新属性添加到另一个具有不同长度的数组的对象数组中,因此一旦数组完成迭代,它将再次从第一个开始

javascript - 我应该将类方法移动到原型(prototype)吗?

javascript - 如何基于 api 调用遍历树/数组 -Javascript