我需要从节点运行一个容器,所以我使用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
,我不知道如何处理这两个问题。但上面的作品
答案 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());