【问题标题】:Node child process exec async only called once节点子进程执行异步只调用一次
【发布时间】:2023-03-29 02:03:01
【问题描述】:

我有一个带有一些 ID 的数组,例如 a = [abc,cde,efg]。我将这个数组和第二个包含适合 ID 的名称传递给 Node.js 中的子进程。 我想等到子进程完成并在此之后处理下一个数组成员。

实现它的代码是(建议编辑):

function downloadSentinel(promObj) {
return new Promise((resolve,reject) => {
    function makeRequest(url, i, callback) {
        url = promObj.ID;
        name = promObj.Name;
        var sys = require('util'),
            exec = require('child_process').exec,
            child;

        var directory = __dirname.substring(0, __dirname.indexOf("\\app_api"));
        console.log(directory);



        child = exec(directory + '\\downloadProducts.sh' + promObj.ID[i] + ' ' + promObj.Name[i], function (error, stdout, stderr) {
            child.on("error", function (error) {
                console.log(error);
            })

            child.stdout.on('data', function (data) {
                console.log(data.toString());
            });

            child.on('exit', function(exit) {
            console.log(exit);    
            callback();


            })


        })



    }

    async.eachOfLimit(promObj.requestURLS, 2, makeRequest, function (err) {
        if (err) reject(promObj)
        else {
            resolve(promObj);
        }
    });
});
}

我正在使用 npm-async 来控制并发流,因为我想限制我在 shell 脚本中执行的 curl 请求。 shell sript 可以正常工作。现在由于async.eachOfLimit 的限制,该脚本只被调用了两次。然后不再处理其他数组 ID。

编辑

这是我最后尝试的代码,但随后所有可能的 url 都被调用了,而不是只有 2 个。我在这里找到了这个Another Stackoverflow question。我也试过 async.timesLimit

function downloadSentinel(promObj,req,res) {
     async.eachOfLimit(promObj.requestURLS, 2,function (value,i,callback) {
         console.log('I am here ' + i + 'times');
         url = promObj.requestURLS;
         name = promObj.Name;
         console.log(promObj.requestURLS);
         var sys = require('util'),
             exec = require('child_process').exec,
             child;

         var directory = __dirname.substring(0, __dirname.indexOf("\\app_api"));
         console.log(directory);

         console.log("executing:", directory + '\\downloadProducts.sh ' + promObj.requestURLS[i] + ' ' + promObj.Name[i]);
         child = exec(directory + '\\downloadProducts.sh' + ' ' + promObj.requestURLS[i] + ' ' + promObj.Name[i], function (error, stdout, stderr) {

             if (error != null){
                 console.log(error);
             }



            // this task is resolved
            return  callback(error, stdout);
         });

     }, function (err) {
        if (err) console.log('error')
        else {
            console.log('Done');
        }
    });

     }

我错过了什么?提前致谢。

【问题讨论】:

  • 只需将您的回调放入on('exit')

标签: node.js asynchronous child-process


【解决方案1】:

exec 是异步的,它不会等待启动的进程完成。

将调用移至child.on('exit' ...) 处理程序内的callback() 或使用execSync

【讨论】:

  • 谢谢。现在我有了探针,只下载了数组的两个项目,然后什么也没有发生。回调是否结束了整个 `async.eachOfLimit()` 函数?
  • 不,您将 eachOfLimit 的 limit 参数设置为 2(第二个参数),这限制了异步操作的数量。
  • 我对这个函数的理解如下:假设数组中有5个项目。函数makeRequest 被调用了2 次,因此数组中的前两项被下载。回调后,下载下两个项目,依此类推。我想对了吗?
  • 是的,你想的没错,我误解了limit的意思。重新阅读文档很明显,当所有项目都被迭代或发生错误时会调用 eachOfLimit 回调(这应该会停止迭代),所以这可能就是你的情况。
  • 我发现取决于我设置子进程被调用次数的限制。回调后函数结束并且不再被调用。有什么想法吗?
猜你喜欢
  • 2016-08-23
  • 1970-01-01
  • 2014-02-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-18
  • 1970-01-01
  • 2020-03-30
相关资源
最近更新 更多