Reputation: 6839
I am trying to refactor code where I use anti pattern but still don't understand how exactly to refactor something like this: I have a function that work like this now:
export async function submit(data) {
return new Promise(async function(resolve, reject) {
...
let list = await getList();
...
for (let i = 0; i < list.length; i++) {
let data = await getData(list[i]);
}
...
for (let i = 0; i < list.length; i++) {
let response = await uploadFile(list[i]);
}
And I call this function like:
let response = await submit(data);
I understand that async function in new Promise is problem but how to fix it?
export async function submit(data) {
return new Promise(async function(resolve, reject) {
let files = getFiles();
let prepareUrlsResponse = await prepareUrls(paths);
if (prepareUrlsResponse.error === true) {
resolve( { success: false });
} else {
let blobs = [];
for (let i = 0; i < prepareUrlsResponse.data.length; i++) {
let fileData = await RNFetchBlob.fs.stat(filePath);
blobs.push(fileData);
}
for (let i = 0; i < blobs.length; i++) {
let item = blobs[i];
let response = await uploadFile(
item.url,
item.blob
);
if (response && response.uploadSuccess === false) {
resolve( { success: false });
break;
}
}
}
api.post(
endpoint,
data,
response => {
if (response.ok) {
resolve( { success: true, response: response });
} else {
resolve( { success: false });
}
}
);
});
}
Upvotes: 0
Views: 83
Reputation: 664920
Just drop the line entirely. Your submit
already is an async function
, you can use await
directly within it. There's no need to create a new Promise
around the whole thing, you need it only to promisfy the api.post
call. You should factor that out into a separate function returning a promise and use await
on it like on the other functions you are calling.
function postData(url, data) {
return new Promise(function(resolve, reject) {
// ^^^^^^^^ no `async` here!
api.post(url, data, resolve);
});
}
export async function submit(data) {
let files = getFiles();
let prepareUrlsResponse = await prepareUrls(paths);
if (prepareUrlsResponse.error === true) {
return { success: false };
} else {
let blobs = [];
for (let i = 0; i < prepareUrlsResponse.data.length; i++) {
let fileData = await RNFetchBlob.fs.stat(filePath);
blobs.push(fileData);
}
for (let i = 0; i < blobs.length; i++) {
let item = blobs[i];
let response = await uploadFile(
item.url,
item.blob
);
if (response && response.uploadSuccess === false) {
return { success: false };
}
}
}
const response = await postData(endpoint, data);
if (response.ok) {
return { success: true, response: response });
} else {
return { success: false };
}
}
You could of course inline the postData
call and use const response = await new Promise(…);
, but you should only wrap the callback parts and not your whole logic.
Upvotes: 3