我如何等待拉动?
How do I wait for a pull?
我需要从节点 运行 一个容器,所以我使用 dockerode
模块,它使用 Docker API。对于 运行 一个容器,我首先需要拉取图像(如果它在本地不存在)。为了简单起见,我已经 promisified 调用,但我很难弄清楚如何连接调用,特别是关于 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()
的结果丢失了但是如果我想在 运行ning 之后检查我需要 o
但我不知道如何处理两者。但上面的作品
泛泛而谈,假设你有:
return createsPromiseA().then((a) => {
takesNodebackB(a, (err, b) => {
let promiseC = createsPromiseC();
// How do I return promiseC??
});
});
有2个答案。一个使用原生承诺 ootb:
return createsPromiseA().then((a) => {
return new Promise((resolve, reject) => {
takesNodebackB(a, (err, b) => {
if (err) return reject(err);
resolve(b);
});
});
}).then((b) => createsPromiseC());
这里的技巧是将 nodeback 函数包装在一个 promise 中。
第二个答案是 bluebird 附带 http://bluebirdjs.com/docs/api/promise.promisify.html,虽然我没有使用它,但 应该 允许你做同样的事情,比如:
return createsPromiseA()
.then((a) => bluebird.promisify(takesNodebackB)(a))
.then((b) => createsPromiseC());
我需要从节点 运行 一个容器,所以我使用 dockerode
模块,它使用 Docker API。对于 运行 一个容器,我首先需要拉取图像(如果它在本地不存在)。为了简单起见,我已经 promisified 调用,但我很难弄清楚如何连接调用,特别是关于 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()
的结果丢失了但是如果我想在 运行ning 之后检查我需要 o
但我不知道如何处理两者。但上面的作品
泛泛而谈,假设你有:
return createsPromiseA().then((a) => {
takesNodebackB(a, (err, b) => {
let promiseC = createsPromiseC();
// How do I return promiseC??
});
});
有2个答案。一个使用原生承诺 ootb:
return createsPromiseA().then((a) => {
return new Promise((resolve, reject) => {
takesNodebackB(a, (err, b) => {
if (err) return reject(err);
resolve(b);
});
});
}).then((b) => createsPromiseC());
这里的技巧是将 nodeback 函数包装在一个 promise 中。
第二个答案是 bluebird 附带 http://bluebirdjs.com/docs/api/promise.promisify.html,虽然我没有使用它,但 应该 允许你做同样的事情,比如:
return createsPromiseA()
.then((a) => bluebird.promisify(takesNodebackB)(a))
.then((b) => createsPromiseC());