4 回答
TA贡献2065条经验 获得超13个赞
首先,您需要为异步函数添加一个回调参数,删除 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。现在,您知道调用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()
.
添加回答
举报