我有一大堆的返回,我想使廣義承諾的功能,所以我寫出來是這樣的:模塊化的承諾和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;
}
我在每個函數解析數據,因爲我計劃有很多這些類型的功能,我不知道他們會在鏈接時被調用的順序:
readfile(somedata)
.then(upload)
.then(delete)
.then(save)
//etc
這工作得很好,直到我必須做Promise.all:
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
使用Promise.all().then(upload)
會給我帶來錯誤,因爲Promise.all()返回的新諾言是包含checkWebpageForReference
和takeScreenshot
兩個分辨率的對象。本質上,在readFile
中,我無法訪問data
字段,因爲由此產生的承諾是[data, data]
。
有沒有一種模式可以幫助我實現我需要做的事情?我需要使承諾模塊爲他們提供儘可能多的數據。
那麼,你的每個函數都遵循一些通用的接口嗎?即'prf1'和'prf2'都返回包含'new_variable1'的對象?如果不是,如果它不知道它接收的是什麼,你怎麼能使'prf3'一致? –
@MattWay他們沒有真正的模式。我只是在鏈接的時候把它放到他們的使用上。我意識到這使得它容易出錯,但我還沒有找到一個更好的方法來做到這一點。這些函數只是假定'data'包含他們要求的字段。如果鏈條設計的很好,那麼他們會。但我不確定如何標準化。 – db2791
你能舉一個例子說明你想'prf3'看起來像內部嗎? –