2016-07-08 81 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

目前調用失敗,因爲圖像還沒有時間加載。我看到在docs: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 - 電子

*解決*

按以下約書亞的答案,這裏的工作代碼:

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()); 

這裏的技巧是包裝節點的功能在承諾。

第二個答案是,藍鳥附帶http://bluebirdjs.com/docs/api/promise.promisify.html它,雖然我沒有用它,應該讓你做同樣的事情,是這樣的:

return createsPromiseA() 
    .then((a) => bluebird.promisify(takesNodebackB)(a)) 
    .then((b) => createsPromiseC()); 
相關問題