2016-07-08 4 views
0

Мне нужно запустить контейнер из узла, поэтому я использую модуль 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 только огнь, когда тянуть закончен, но проблема в том, что я сломана обещания. Каков правильный способ борьбы с этим?

ТИА - е

* ПОСТАНОВИЛИ *

согласно ответу Иисуса Навина ниже, здесь работает код:

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, и я не знаю, как обращаться с ними обоими. но выше работает

ответ

2

Говоря в общих чертах здесь, предположим, что у вас есть:

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 в обещании.

Второй ответ, что Bluebird поставляется с http://bluebirdjs.com/docs/api/promise.promisify.html, которые, в то время как я не использовал его, должны позволяют делать то же самое, что-то вроде:

return createsPromiseA() 
    .then((a) => bluebird.promisify(takesNodebackB)(a)) 
    .then((b) => createsPromiseC());