4 回答

TA貢獻2065條經驗 獲得超14個贊
首先,您需要為異步函數添加一個回調參數,刪除 async 關鍵字
const uploadToAWSBucket = (fileObject, callback) => {
接下來,您需要以回調方式處理 s3 響應,將 Promise 替換為回調使用。
s3.upload(AWSUploadObject, (err, data) => {
if (err) {
callback(err);
return;
}
callback(null, data);
});
或者你甚至可以將其簡化為
s3.upload(AWSUploadObject, callback)
您還需要將您的使用更新為回調方式
uploadToAWSBucket(file, (error, image1) => {
if (error) {
next(error);
return;
}
// your success code here
});
最終結果是
const uploadToAWSBucket = (fileObject, callback) => {
let randomFileName = shortid.generate();
const AWSUploadObject = {
Bucket: BUCKET_NAME,
Key: randomFileName,
Body: fileObject.buffer,
ContentType: fileObject.mimetype,
};
s3.upload(AWSUploadObject, callback);
};
而已。我希望這個解釋能幫助你理解如何使用回調。

TA貢獻1802條經驗 獲得超5個贊
如果我的理解是正確的,你要image1
在catch
block之后使用。
在這種情況下,我想,您將使用image1
. 可以按如下方式完成,其中一些片段來自此答案:
const uploadToAWSBucket = (fileObject, callback) => { ... }; // described in the linked answer
uploadToAWSBucket(file, function callback(error, image1) {
if(error) { return next(error); }
someOtherFunction(image1, next); // "next" is passed as callback, with the assumption that nothing else needed to be called after that.
});
如果你想用 的結果調用另外 2 個函數someOtherFunction,可以這樣做:
uploadToAWSBucket(file, function callback(error, image1) {
if(error) { return next(error); }
someOtherFunction(image1, function someOtherFunctionCb(error, someOtherFunctionResult) {
if(error) { return next(error); }
someOtherFunction2(someOtherFunctionResult, function someOtherFunction2Cb(error, someOtherFunction2Result) {
if(error) { return next(error); }
someOtherFunction3(someOtherFunction2Result, function someOtherFunction3Cb(error, someOtherFunction3Result) {
if(error) { return next(error); }
next(null, someOtherFunction3Result);
});
});
});
});
基本上,如果您使用回調,則不能擁有局部全局變量。我將嘗試解釋一個問題的情況。
let image1 = null;
uploadToAWSBucket(file, function uploadToAWSBucketCallback(error, _image1) {
if(error) { return next(error); }
image1 = _image1;
});
someOtherFunction(image1, function someOtherFunctionCb(error, someOtherFunctionResult) {
if(error) { return next(error); }
...
});
在上面的代碼片段中,someOtherFunction將在uploadToAWSBucketCallback執行之前調用。這意味著,image1沒有分配給_image1?,F在,您知道調用image1when的值是多少someOtherFunction。
第二個片段顯示了如何通過將后續調用嵌套在回調中來將一個異步函數的結果傳遞給另一個。這使許多人的代碼可讀性降低。有類似的庫async,這有助于使事情變得更容易和可讀。
第二個片段可以用async庫的waterfall函數重寫,如下所示:
async.waterfall([
function uploadToAWSBucketStep(callback) {
uploadToAWSBucket(file, callback);
},
function someOtherFunctionStep(image1, callback) {
someOtherFunction(image1, callback);
},
function someOtherFunction2Step(someOtherFunctionResult, callback) {
someOtherFunction2(someOtherFunctionResult, callback);
},
function someOtherFunction3Step(someOtherFunction2Result, callback) {
someOtherFunction3(someOtherFunction2Result, callback);
}
], function lastStep(error, someOtherFunction3Result) {
if(error) { return next(error); };
next(null, someOtherFunction3Result);
});

TA貢獻1794條經驗 獲得超7個贊
在閱讀了每個人的回復后,我想出了以下我認為可行的方法,基本上是@Pavlo Zhukov 建議的。(請注意,函數名稱與我之前的帖子略有不同。)
來自父函數的代碼:
let image1;
uploadToAWSBucketCallbackStyle(file, (err, data) => {
if (err) {
return next(err);
}
image1 = data;
// Do stuff with image1 here or make additional function
// calls using image1.
});
子函數:
const uploadToAWSBucketCallbackStyle = (fileObject, callback) => {
let randomFileName = shortid.generate();
const AWSUploadObject = {
Bucket: BUCKET_NAME,
Key: randomFileName,
Body: fileObject.buffer,
ContentType: fileObject.mimetype,
};
s3.upload(AWSUploadObject, callback);
}

TA貢獻1829條經驗 獲得超13個贊
Promisifcation 基于回調的函數是很好理解和有據可查的。
我從未見過關于“去承諾”的討論,但這很簡單。
從您開始uploadToAWSBucket()
并假設您希望您的回調是“nodeback”樣式(簽名(err, data)
),那么您可以編寫:
const uploadToAWSBucketNodeback = (fileObject, nodeback) => {
uploadToAWSBucket(fileObject) // call the promise-returning "async" version.
.then(data => { // success path
nodeback(null, data);
})
.catch(nodeback); // error path
};
或者你可以寫一個通用的去承諾...
const depromisify = (asyncFunction) => {
return function(...params) {
let nodeback = params.pop(); // strip nodeback off the end of params
asyncFunction(...params)
.then(data => { // success path
nodeback(null, data);
})
.catch(nodeback); // error path
}
};
... 然后
const uploadToAWSBucketNodeback = depromisify(uploadToAWSBucket);
任何一種方法都允許您編寫:
uploadToAWSBucketNodeback(fileObject, function(err, data)) {
if(err) {
// handle error
} else {
// handle data
}
}
筆記
我們只需要知道原始的 asyncFunction 是 thenable/catchable 即可。
原始的 asyncFunction 對 depromisified 函數完全不透明。
我們不需要了解原始 asyncFunction 的內部工作原理。因此,
AWSUploadObject
不需要復制的組成......它仍然由uploadToAWSBucket()
.
添加回答
舉報