簡體   English   中英

Node.js模塊中的異步功能

[英]Async functions in Node.js module

我是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);
    })
};

現在,我還有一個main.js在其中調用以下函數:

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

var output1 = module.myFunction1();

var output2 = module.myFunction2();

我的第一個問題是我的函數返回undefined 我了解這是因為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;
    }
}

我的main.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

我的問題現在是,即使myFunction2()首先完成,myFunction1()總是在myFunction2()之前記錄。 我是否了解有關Promises的問題? 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);
});

在您的情況下,使用回調是最簡單的解決方案,但是您應該意識到還有其他模式可以處理異步執行。 這是一個很好的概述 例如,一種流行的解決方案是使用promises ,這在您必須鏈接異步延續時特別有趣,它可以允許

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);
})

首先,我建議您處理模塊中的錯誤( errstderr )。 如您所見,您的函數采用一個參數,即回調。 如果您的異步函數運行,則調用回調函數。 因此,您可以像這樣使用它:

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

exec函數還接受回調函數(第一個參數錯誤err錯誤的第一個回調)。 還有其他方法可以處理異步代碼的流控制(例如,庫async )。 您還可以了解Promises ,它是今天的錯誤優先回調的替代方法。

回調函數不會直接返回值...您需要的是設置讀取值時將發生的情況。 像這樣:

my_function(what_will_happen_when_my_function_will_get_finished());

exectly:

myFunction1(function(data){console.log('hello! I've finished, and received: '+data);});

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM