我怎么等待拉?

时间:2016-07-08 02:55:41

标签: node.js docker bluebird

我需要从节点运行一个容器,所以我使用dockerode模块,它使用Docker API。要运行容器,我首先需要提取图像(如果它不在本地存在)。我已经宣传要求简单,但我很难弄清楚如何连接来电,尤其是pull提供的回调。这就是我所拥有的:

init: function(opts) {
    var self = this;
    self.docker = new Docker();
    self.pull = Bluebird.promisify(
        self.docker.pull, { context: self.docker }
    );  
    self.createContainer = Bluebird.promisify(
        self.docker.createContainer, { context: self.docker }
    );  
},  

run: function(opts) {
    var self = this;
    return self.createContainer(opts).catch(function(e) {
        return self.pull(opts.Image).then(function(stream) {
            return self.createContainer(opts);
        }); 
    }).then(function(o) {;
        var start = Bluebird.promisify(
            o.start, { context: o } 
        );  
        return start({});
    }).then(function(o) {;
        var inspect = Bluebird.promisify(
            o.inspect, {context: o}
        );  
        return inspect();
    }); 
},  

所以会发生的情况是第一个createContainer失败(因为图片尚未加载)并且会发生对pull的调用。如果成功,则调用createContainer

目前该呼叫失败,因为图像还没有时间加载。我在文档中看到:https://github.com/apocas/dockerode(参见帮助函数),我可以做到:

        return self.pull(opts.Image).then(function(stream) {
            self.docker.modem.followProgress(stream, function(err, output) {
                return self.createContainer(opts);
            });
        }); 

...我认为createContainer只会在拉动结束时触发,但问题是我已经违背了承诺。什么是解决这个问题的正确方法?

TIA - e

*已解决*

根据Joshua在下面的回答,这里有工作代码:

init: function(opts) {
    var self = this;
    self.docker = new Docker();
    self.pull = Bluebird.promisify(
        self.docker.pull, {context: self.docker}
    );  
    self.createContainer = Bluebird.promisify(
        self.docker.createContainer, {context: self.docker}
    );  
    self.followProgress = Bluebird.promisify(
        function(stream, done) {
            return self.docker.modem.followProgress(stream, done);
        },  
        {context: self.docker.modem}
    );  
},  
run: function(opts) {
    var self = this;
    return self.createContainer(opts).catch(function(e) {
        return self.pull(opts.Image).then(function(stream) {
            return self.followProgress(stream);
        }).then(function() {
            return self.createContainer(opts);
        }); 
    }).then(function(o) {
        var start = Bluebird.promisify(
            o.start, {context: o}
        );  
        start();
        return o;
    }).then(function(o) {;
        var inspect = Bluebird.promisify(
            o.inspect, {context: o}
        );
        return inspect();
    });
},

我很高兴start()的结果迷失了,但如果我想在跑步后检查,我需要o,我不知道如何处理这两个问题。但上面的作品

1 个答案:

答案 0 :(得分:2)

在这里说一般性,假设你有:

None

有2个答案。一个使用本机承诺ootb附带的东西:

return createsPromiseA().then((a) => {
  takesNodebackB(a, (err, b) => {
    let promiseC = createsPromiseC();
    // How do I return promiseC??
  });
});

这里的技巧是将nodeback函数包装在promise中。

第二个答案是蓝鸟与http://bluebirdjs.com/docs/api/promise.promisify.html一起发货,虽然我还没有使用它,允许你做同样的事情,如:

return createsPromiseA().then((a) => {
  return new Promise((resolve, reject) => {
    takesNodebackB(a, (err, b) => {
      if (err) return reject(err);
      resolve(b);
    });
  });
}).then((b) => createsPromiseC());