我需要实现以下逻辑。
我需要下载图片,但有时候下载的文件已损坏,所以我需要再次尝试下载。以下是我的下载承诺的样子。
return Downloader.downloadImage(downloadUrl, fileName).then((filename) => {
// Update some info, save ... and return new promise
return doStuffAndReturnPromise(filename);
});
但正如我上面所描述的,我需要验证下载的文件是否是有效的图像,然后才能成功返回承诺。
这是一个骨架。
return new Promise(function (resolve, reject) {
let retryCounter = MyService.RETRY_COUNT;
let success = false;
while (retryCounter > 0 && !success) {
// Run new promise but wait until it completes
// Decrease the counter
retryCounter--;
}
});
这里的问题是我需要同步运行下载承诺,然后继续迭代并运行新的承诺。
请建议优雅地解决此问题的最佳方法。
感谢。
答案 0 :(得分:0)
你可以返回一个再次尝试的Promise而不是answear,如下所示:
import paramiko
import time
def ssh_session(ip):
try:
session = paramiko.SSHClient() #Open the session
session.set_missing_host_key_policy(paramiko.AutoAddPolicy())
session.connect(ip, username = "ciscouser1", password = "password")
connection = session.invoke_shell()
####Running Cisco IOS commands###
connection.send("enable\n")
connection.send("password1") #sending
connection.send("\n")
connection.send("configure terminal\n\n")
time.sleep(1)
connection.send("do show ip int brief\n")
time.sleep(1)
except paramiko.AuthenticationException:
print "wrong credentials"
ssh_session("10.10.10.1")
您可以像这样使用它:
var maxAttempts = 5
var counter = 0
return Downloader.downloadImage(downloadUrl, fileName).then((filename) => {
// Update some info, save ... and return new promise
if (checkIfNeedToTryAgain()) {
counter++;
if (counter > maxAttempts) {
throw maxAttemptsError
}
// Try again
return Downloader.downloadImage(downloadUrl, fileName)
}
// In case of success
return doStuffAndReturnPromise(filename);
});
答案 1 :(得分:0)
我在前一段时间(http://jsbin.com/xefutos/6/edit?html,js,output)写了这个例子,你应该能够根据自己的需要进行调整:
// Function that returns a promise
var searchForNumber = function(number) {
return new Promise(function(resolve, reject) {
setTimeout(function() {
var min = 1;
var max = 10;
var val = Math.floor(Math.random()*(max-min+1)+min);
console.log('Value is: ' + val.toString());
return resolve(val);
}, 1000);
});
};
// fn : function that should return a promise.
// args : the arguments that should be passed to fn.
// donefn : function that should check the result of the promise
// and return true to indicate whether ploop should stop or not.
// promise: A promise value that is used internally by ploop and should never
// be passed in by the caller of ploop.
var ploop = function(fn, args, donefn, promise) {
return (promise = promise || Promise.resolve(true))
.then(function() {
return(fn.apply(null, args));
})
.then(function(result) {
var finished = donefn(result);
if(finished === true){
return result;
} else {
return ploop(fn, args, donefn, promise);
}
});
};
var searchFor = 4;
var donefn = function(result) {
return result == searchFor;
};
console.log('Searching for: ' + searchFor);
ploop(searchForNumber, [searchFor], donefn)
.then(function(val) {
console.log('Finally found! ' + val.toString());
process.exit(0);
})
.catch(function(err) {
process.exit(1);
});
答案 2 :(得分:0)
我发现Observer模式在这些场景中非常有用,因为它使代码更具可读性和可重用性。这是代码的样子
// MyObservable.js
var util = require('util');
var EventEmitter = require('events').EventEmitter;
function MyObservable() {
EventEmitter.call(this);
}
MyObservable.prototype.downloadImage = function(imageUrl) {
// download image code and validate
if (imageIsValid) {
this.emit('done', 'valid image');
} else {
this.emit('error', 'invalid image')
}
}
以上是下载代码。国际海事组织,它在未来也更可重复使用,或者有不同的观察员对其采取行动。
const MyObservable = require('./MyObservable');
const observable = new MyObservable();
let retryCount = 3;
observable.on('done', (message) => {
console.log('Download completed');
});
observable.on('error', (message) => {
retryCount -= 1;
if (retryCount > 0) {
observable.downloadImage(imageUrl);
}
});
observable.downloadImage(imageUrl);