我初学javascript并尝试构建一个干净的对象以在我的用例中使用Dockerode库。我有一个异步问题,我的第27行在24之前执行,我不明白为什么以及如何解决它!
此外,如果您感觉更方便,请访问此公开要点:https://gist.github.com/msitruk/2cdb655a0bebdb29c61d8bc5606a2695
{{1}}
答案 0 :(得分:3)
如果你的链接承诺,请不要忘记回复你的下一个承诺..
例如..
.then(()=>{
this.checkReadyScraper();
}
如果checkReadyScraper()
是承诺,那么您将要返回它。
例如
.then(()=>{
return this.checkReadyScraper();
}
否则你所做的一切都在运行checkReadyScraper()
并完全忽略了返回的Promise。
以下是我认为你的runExec看起来如何。我假设exec.inspect
是您要解决的问题。
SearchUtils.prototype.runExec = function (container, cmd) {
return new Promise ((resolve, reject)=>{
let options = {
Cmd: [ '/bin/bash', '-c', cmd ],
AttachStdout: true,
AttachStderr: true
};
container.exec(options, (err, exec) => {
if (err) return reject(err); //return error
exec.start((err, stream) => {
if (err){
console.log("error : "+err);
return reject(err); //return error
}
// container.modem.demuxStream(stream, process.stdout, process.stderr)
if (cmd === "cat /home/immobot/status"){
let newStream = require('stream');
let logStream = new newStream.PassThrough();
logStream.on('data', (chunk) => {
// console.log(chunk.toString('utf8'));
if (chunk.toString('utf8').indexOf("ready") !== -1){
console.log("CONTAINER READY !!");
//EDIT CONTAINER STATUS IN SCRAPERLIST TO READY
this.changeStatusToReady(container.id);
}
});
container.modem.demuxStream(stream, logStream, process.stderr);
}
else if (cmd === "torify scrapy crawl seloger -o seloger.json"){
console.log("on lance le scrape sur un des scraper rdy");
container.modem.demuxStream(stream, process.stdout, process.stderr)
}
// container.modem.demuxStream(stream, logStream, process.stderr);
exec.inspect(function(err, data) {
if (err){
console.log("error : "+err);
//don't forget to return the rejection
return reject(err);
}
//looks like everything was ok, lets resolve
resolve(data);
});
});
});
//resolve("ok"); too early
// TODO ADD EROR STRATEGY
//reject("error"), pointless
});
};

答案 1 :(得分:0)
执行任务(在代码中的第81行使用container.exec),从其余步骤开始异步运行,完成后进行回调。 如果订单很重要,您必须确保在运行scrap命令之前完成刮刀的所有检查。
答案 2 :(得分:0)
首先 - 不需要在每次then()调用中处理错误。 您可以实现单个错误捕获,它将捕获序列中任何then()项中的错误:
.then(()=> {
this.checkReadyScraper();
})
.then(() => {
this.scrap();
})
.catch(e => console.log(e))
另请注意,像catch(e => console.log(e))这样的箭头函数并不需要{}和;
您的问题是您的任务是异步。如果你想链接任务 - 你应该创建一个返回Promise的任务
这是你应该重构的一个粗略的例子:
//Should return Promise
SearchUtils.prototype.exec = function(type, containerId){
let container = docker.getContainer(containerId);
if (type === "getStatus"){
//runExec should return us a Promise
return this.runExec(container, 'cat /home/immobot/status');
}
else if (type === "scrap") {
return this.runExec(container, 'torify scrapy crawl seloger -o seloger.json');
}
};
SearchUtils.prototype.runExec = function (container, cmd) {
return new Promise(function(resolve, reject) {
//do some stuff
//then call resolve(result)
//or call reject(error)
});
}
在此之后,你将能够链接Promises(这实际上非常棒,并有助于解决回调地狱):
.then(()=> {
//this not returns Promise, and it will be correctly chained
return this.checkReadyScraper();
})
.then(() => {
//this not returns Promise, and it will be correctly chained
return this.scrap();
})
.catch(e => console.log(e))
另外,为了使这看起来更干净,我甚至建议做一些小的重构,这最终会给你oneliner:
.then(this.checkReadyScraper).then(this.scrap).catch(console.log)