Node.js从q all顺序运行多个childProcess.execFile进程

时间:2015-01-21 18:28:06

标签: node.js q

我正在编写批量打印图纸的程序。他们需要按照一定的顺序排序。绘制A,B,C。程序绘制正确的打印数量,其顺序是随机的。我需要数组列表中的第一个在下一个之前完成,依此类推。

    startMe(newPaths)
        .then(function(result){

        })

    function startMe(dwgPaths){
       return q.all(buildCalls(dwgPaths));
    }       
    var buildCalls = function(dwgPaths) {
        var calls = [];
        var scFiles = [tmpDir + "425011-fab.scr",tmpDir + "425011-pk.scr",tmpDir + "425011-sc.scr"];
        for (var sc in scFiles){
            for (var i in dwgPaths) {

                calls.push(callAccoreConsole(dwgPaths[i],scFiles[sc]));
            }
        }
        return calls;
    };
    function callAccoreConsole(dwgPath,scrFile){
        var deferred = q.defer();
        childProcess.execFile('C:/Program Files/Autodesk/AutoCAD 2015/accoreconsole.exe',['/i',dwgPath,'/s',scrFile], function(err, data) {
            if(err)
                deferred.resolve({success:false,reason: err});
            deferred.resolve({success:true});
        });
        return deferred.promise;
    }

下面的代码以我想要的方式工作。我打印2个文件,每个3份。文件A使用脚本1,然后文件B使用脚本1.然后重复其他脚本。我总共有6张照片"三组" A,B,A,B,A,B各自运行相应的脚本。使用上面的代码,我可以得到B,A,A,B,A,A。

                callAccoreConsole(newPaths[0],scFiles2[0])
                    .then(function(result){
                        callAccoreConsole(newPaths[1],scFiles2[0])
                            .then(function(result){
                                callAccoreConsole(newPaths[0],scFiles2[1])
                                    .then(function(result){
                                        callAccoreConsole(newPaths[1],scFiles2[1])
                                            .then(function(result){
                                                callAccoreConsole(newPaths[0],scFiles2[2])
                                                    .then(function(result){
                                                        callAccoreConsole(newPaths[1],scFiles2[2])
                                                            .then(function(result){

                                                            })
                                                    })
                                            })
                                    })
                            })
                    });

我一直在努力解决这个问题。我找到了下面的代码并让它适用于我的应用程序,但它似乎并不是最有效的编写方式。如果有人有更紧凑的方式请告诉我。谢谢

          var itemsToProcess = [];
                for (var sc in scFiles){
                    for (var i in newPaths) {
                        itemsToProcess.push( {file:newPaths[i],script:scFiles[sc]});
                    }
                }
                function getDeferredResult(a) {
                    return (function (items) {
                        var deferred;

                        if (items.length === 0) {
                            return q.resolve(true);
                        }

                        deferred = q.defer();
                        var payload = {
                            file:items[0].file,
                            script:items[0].script
                        };
                        callAccoreConsole2(payload)
                            .then(function(result){
                                deferred.resolve(items.splice(1));
                            });
                        return deferred.promise.then(getDeferredResult);
                    }(a));
                }

                q.resolve(itemsToProcess)
                    .then(getDeferredResult)
                    .then(function(result){
                        return res.send({success:true});
                    }) 

1 个答案:

答案 0 :(得分:0)

在构建promise数组时,您同时调用execFile方法。

function callAccoreConsole(dwgPath,scrFile){
    var deferred = q.defer();
    childProcess.execFile('C:/Program Files/Autodesk/AutoCAD 2015/accoreconsole.exe',['/i',dwgPath,'/s',scrFile], function(err, data) {
        if(err)
            deferred.resolve({success:false,reason: err});
        deferred.resolve({success:true});
    });
    return deferred.promise;
}

所以,使用callAccoreConsole来运行进程并返回一个deffered,你需要最终调用该方法的东西 -

calls.push(q.fcall(callAccoreConsole, dwgPaths[i],scFiles[sc]));

我没有特别尝试过这个,但要点是你在为你创造延迟的同时调用你的方法。