ich eine Reihe von Funktionen, die Versprechen zurück, die ich verallgemeinert machen wollen, und so schreibe ich sie wie folgt aus:Modular Versprechungen und Promise.all()
function checkWebpageForReference(data){
//checks a webpage for the reference in html
var promise = new Promise(function(resolve,reject){
fetchUrl(data.url, function(err, meta, body){
if (err) { reject(err); } else {
console.log(body)
if (body.toString().indexOf(data.text) !== -1){
resolve(data);
} else {
reject("Could not find quote");
}
}
});
});
return promise;
}
function takeScreenshot(data){
//takes a screenshot of a webpage and saves it to the file system
//TODO: Mouse coordinates
data.id = shortid.generate();
data.filename = data.id+'.png';
var promise = new Promise(function(resolve,reject){
webshot(data.url, data.filename, { shotOffset: {left: data.mouseX, top: data.mouseY} }, function(err) {
if (err) { reject(err); } else {
resolve(data);
}
});
});
return promise;
}
function uploadReferencePictureToS3(data){
//uploads a picture to S3
var promise = new Promise(function(resolve, reject){
s3.putObject({
ACL: 'public-read',
Bucket: S3_BUCKET,
Key: data.id,
Body: data.picturedata,
ContentType: "image/jpg"
}, function(err) {
if (err) { reject(err); } else {
resolve(data);
}
});
});
return promise;
}
function saveNewReferenceToDb(data){
//saves a new Reference to the database
var promise = new Promise(function(resolve, reject){
new Reference({
_id: data.id,
url: data.url,
text: data.text,
screenshot_url: AWS_S3_URL + data.id,
created_by: "Daniel"
}).save(function(err, saved){
if (err) { reject(err); } else {
data.newReference = saved;
resolve(data);
}
});
});
return promise;
}
function readFile(data){
//reads a file from the file structure and stores it in a variable
var promise = new Promise(function(resolve,reject){
console.log(data);
fs.readFile(data.filename, function(err, picturedata){
console.log(picturedata);
if (err) { reject(err); } else {
data.picturedata = picturedata;
resolve(data);
}
}) ;
});
return promise;
}
function deleteFile(data){
//deletes a file from the file structure
var promise = new Promise(function(resolve, reject){
fs.unlink(data.filename);
resolve(data);
});
return promise;
}
ich in jedem Funktionsdaten lösen, weil ich planen eine Menge von diesen Arten von Funktionen zu haben, und ich weiß nicht, den Auftrag werden sie gerufen werden, während Verkettungs:
readfile(somedata)
.then(upload)
.then(delete)
.then(save)
//etc
das funktioniert gut, bis ich Promise.all zu tun haben:
Promise.all([
referenceTools.checkWebpageForReference(req.body),
referenceTools.takeScreenshot(req.body)
])
.then(function(results){
utils.readFile(results[1])
.then(referenceTools.uploadReferencePictureToS3)
.then(utils.deleteFile)
.then(referenceTools.saveNewReferenceToDb)
.then(function(data){
res.json(data.newReference);
})
.catch(function(err){
utils.errorHandler(err);
res.send("There was an internal error. Please try again soon.");
});
})
.catch(function(err){
utils.errorHandler(err);
res.send("There was an internal error. Please try again soon.");
});
//my very ugly way of doing it
Die Verwendung von Promise.all().then(upload)
gibt mir Fehler, weil die neue Versprechen von Promise.all() ist ein Objekt, das beide Auflösungen von checkWebpageForReference
und takeScreenshot
enthält. Im Wesentlichen, in readFile
, kann ich nicht auf data
Felder zugreifen, weil das resultierende Versprechen [data, data]
ist.
Gibt es ein Muster, dem ich folgen kann, um mir zu helfen, das zu erreichen, was ich tun muss? Ich muss die Versprechen machen, ihnen so viele Daten wie möglich zur Verfügung zu stellen.
Also, folgen Sie jeder Ihrer Funktionen einige gemeinsame Schnittstelle? d.h. 'prf1' und' prf2' geben beide Objekte zurück, die 'new_variable1' enthalten? Wenn nicht, wie kann man 'prf3' konsistent machen, wenn es nicht weiß, was es empfängt? –
@MattWay Es gibt nicht wirklich ein Muster, dem sie folgen. Das habe ich bei der Verkettung ihrer Verwendung überlassen. Ich weiß, dass das fehleranfällig ist, aber ich muss noch einen besseren Weg finden. Die Funktionen nehmen nur an, dass "data" ein Feld enthält, nach dem sie fragen. Wenn die Kette gut entworfen ist, dann werden sie es tun. Aber ich bin mir nicht sicher, wie ich das standardisieren soll. – db2791
Können Sie ein Beispiel dafür geben, wie "prf3" intern aussehen könnte? –