为什么第27行在第24行之前执行?

时间:2017-09-13 10:25:10

标签: javascript node.js docker ecmascript-6

我初学javascript并尝试构建一个干净的对象以在我的用例中使用Dockerode库。我有一个异步问题,我的第27行在24之前执行,我不明白为什么以及如何解决它!

此外,如果您感觉更方便,请访问此公开要点:https://gist.github.com/msitruk/2cdb655a0bebdb29c61d8bc5606a2695

{{1}}

3 个答案:

答案 0 :(得分:3)

如果你的链接承诺,请不要忘记回复你的下一个承诺..

例如..

.then(()=>{
  this.checkReadyScraper();
}

如果checkReadyScraper()是承诺,那么您将要返回它。

例如

.then(()=>{
  return this.checkReadyScraper();
}

否则你所做的一切都在运行checkReadyScraper()并完全忽略了返回的Promise。

以下是我认为你的runExec看起来如何。我假设exec.inspect是您要解决的问题。



SearchUtils.prototype.runExec = function (container, cmd) {
    return new Promise ((resolve, reject)=>{
        let options = {
            Cmd: [ '/bin/bash', '-c', cmd ],
            AttachStdout: true,
            AttachStderr: true
        };

        container.exec(options, (err, exec) => {
            if (err) return reject(err); //return error
            exec.start((err, stream) => {
                if (err){
                    console.log("error : "+err);
                    return reject(err); //return error
                }

                // container.modem.demuxStream(stream, process.stdout, process.stderr)

                if (cmd === "cat /home/immobot/status"){
                    let newStream = require('stream');
                    let logStream = new newStream.PassThrough();
                    logStream.on('data', (chunk) => {
                        // console.log(chunk.toString('utf8'));
                        if (chunk.toString('utf8').indexOf("ready") !== -1){
                            console.log("CONTAINER READY !!");
                            //EDIT CONTAINER STATUS IN SCRAPERLIST TO READY
                            this.changeStatusToReady(container.id);
                        }
                    });
                    container.modem.demuxStream(stream, logStream, process.stderr);

                }
                else if (cmd === "torify scrapy crawl seloger -o seloger.json"){
                    console.log("on lance le scrape sur un des scraper rdy");
                    container.modem.demuxStream(stream, process.stdout, process.stderr)
                }

                // container.modem.demuxStream(stream, logStream, process.stderr);

                exec.inspect(function(err, data) {
                    if (err){
                        console.log("error : "+err);
                        //don't forget to return the rejection
                        return reject(err);
                    }
                    //looks like everything was ok, lets resolve
                    resolve(data);
                });
            });
        });
        //resolve("ok"); too early
        // TODO ADD EROR STRATEGY
        //reject("error"), pointless
    });
};




答案 1 :(得分:0)

执行任务(在代码中的第81行使用container.exec),从其余步骤开始异步运行,完成后进行回调。 如果订单很重要,您必须确保在运行scrap命令之前完成刮刀的所有检查。

答案 2 :(得分:0)

首先 - 不需要在每次then()调用中处理错误。 您可以实现单个错误捕获,它将捕获序列中任何then()项中的错误:

.then(()=> {
  this.checkReadyScraper();
})
.then(() => {
  this.scrap();
})
.catch(e => console.log(e))

另请注意,像catch(e => console.log(e))这样的箭头函数并不需要{}和;

您的问题是您的任务是异步。如果你想链接任务 - 你应该创建一个返回Promise的任务

这是你应该重构的一个粗略的例子:

//Should return Promise
SearchUtils.prototype.exec = function(type, containerId){
  let container = docker.getContainer(containerId);
  if (type === "getStatus"){
    //runExec should return us a Promise
    return this.runExec(container, 'cat /home/immobot/status');
  }
  else if (type === "scrap") {
    return this.runExec(container, 'torify scrapy crawl seloger -o seloger.json');
  }
};

SearchUtils.prototype.runExec = function (container, cmd) {
  return new Promise(function(resolve, reject) {
     //do some stuff
     //then call resolve(result)
     //or call reject(error)
  });
}

在此之后,你将能够链接Promises(这实际上非常棒,并有助于解决回调地狱):

.then(()=> {
  //this not returns Promise, and it will be correctly chained 
  return this.checkReadyScraper();
})
.then(() => {
  //this not returns Promise, and it will be correctly chained
  return this.scrap();
})
.catch(e => console.log(e))

另外,为了使这看起来更干净,我甚至建议做一些小的重构,这最终会给你oneliner:

.then(this.checkReadyScraper).then(this.scrap).catch(console.log)