4 回答

TA貢獻(xiàn)2065條經(jīng)驗(yàn) 獲得超14個(gè)贊
首先,您需要為異步函數(shù)添加一個(gè)回調(diào)參數(shù),刪除 async 關(guān)鍵字
const uploadToAWSBucket = (fileObject, callback) => {
接下來(lái),您需要以回調(diào)方式處理 s3 響應(yīng),將 Promise 替換為回調(diào)使用。
s3.upload(AWSUploadObject, (err, data) => {
if (err) {
callback(err);
return;
}
callback(null, data);
});
或者你甚至可以將其簡(jiǎn)化為
s3.upload(AWSUploadObject, callback)
您還需要將您的使用更新為回調(diào)方式
uploadToAWSBucket(file, (error, image1) => {
if (error) {
next(error);
return;
}
// your success code here
});
最終結(jié)果是
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);
};
而已。我希望這個(gè)解釋能幫助你理解如何使用回調(diào)。

TA貢獻(xiàn)1802條經(jīng)驗(yàn) 獲得超5個(gè)贊
如果我的理解是正確的,你要image1
在catch
block之后使用。
在這種情況下,我想,您將使用image1
. 可以按如下方式完成,其中一些片段來(lái)自此答案:
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.
});
如果你想用 的結(jié)果調(diào)用另外 2 個(gè)函數(shù)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);
});
});
});
});
基本上,如果您使用回調(diào),則不能擁有局部全局變量。我將嘗試解釋一個(gè)問(wèn)題的情況。
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執(zhí)行之前調(diào)用。這意味著,image1沒(méi)有分配給_image1?,F(xiàn)在,您知道調(diào)用image1when的值是多少someOtherFunction。
第二個(gè)片段顯示了如何通過(guò)將后續(xù)調(diào)用嵌套在回調(diào)中來(lái)將一個(gè)異步函數(shù)的結(jié)果傳遞給另一個(gè)。這使許多人的代碼可讀性降低。有類(lèi)似的庫(kù)async,這有助于使事情變得更容易和可讀。
第二個(gè)片段可以用async庫(kù)的waterfall函數(shù)重寫(xiě),如下所示:
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貢獻(xiàn)1794條經(jīng)驗(yàn) 獲得超8個(gè)贊
在閱讀了每個(gè)人的回復(fù)后,我想出了以下我認(rèn)為可行的方法,基本上是@Pavlo Zhukov 建議的。(請(qǐng)注意,函數(shù)名稱(chēng)與我之前的帖子略有不同。)
來(lái)自父函數(shù)的代碼:
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.
});
子函數(shù):
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貢獻(xiàn)1829條經(jīng)驗(yàn) 獲得超13個(gè)贊
Promisifcation 基于回調(diào)的函數(shù)是很好理解和有據(jù)可查的。
我從未見(jiàn)過(guò)關(guān)于“去承諾”的討論,但這很簡(jiǎn)單。
從您開(kāi)始uploadToAWSBucket()
并假設(shè)您希望您的回調(diào)是“nodeback”樣式(簽名(err, data)
),那么您可以編寫(xiě):
const uploadToAWSBucketNodeback = (fileObject, nodeback) => {
uploadToAWSBucket(fileObject) // call the promise-returning "async" version.
.then(data => { // success path
nodeback(null, data);
})
.catch(nodeback); // error path
};
或者你可以寫(xiě)一個(gè)通用的去承諾...
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);
任何一種方法都允許您編寫(xiě):
uploadToAWSBucketNodeback(fileObject, function(err, data)) {
if(err) {
// handle error
} else {
// handle data
}
}
筆記
我們只需要知道原始的 asyncFunction 是 thenable/catchable 即可。
原始的 asyncFunction 對(duì) depromisified 函數(shù)完全不透明。
我們不需要了解原始 asyncFunction 的內(nèi)部工作原理。因此,
AWSUploadObject
不需要復(fù)制的組成......它仍然由uploadToAWSBucket()
.
添加回答
舉報(bào)