Problem:
I am trying to execute a series of functions in a specific order. These functions all have asynchronous tasks inside of them; however, these functions need to happen sequentially.
The below code needs to do the following:
Delete current contents of Document Directory (this is because all files are persistent but I do NOT need them for permanent storage, only temporary)
Copy current file assets from their locations to the Document Directory
Zip up the folder of the Document Directory so I can store the zipped folder in AWS
Is it possible to ensure these functions wait for their asynchronous tasks to finish? (Some of these asynchronous tasks are run in a forEach
loop -- this is not a single task within each function).
To take this a step further, can I execute the two (x2) copyFilesToDocumentDirectory()
concurrently and still wait before executing zipDocumentDirectory()
?
import React, { Component } from 'react';
import { zip } from 'react-native-zip-archive';
import RNFS from 'react-native-fs';
export default class AddMedia extends React.Component {
state = {
photoAssets: [],
videoAssets: [],
videoThumbnails: [],
thumbnailReady: false
};
zipDocumentDirectory() {
var path = RNFS.DocumentDirectoryPath;
console.log("Zipped");
zip(path, path "/urls.zip")
.then((path) => {
console.log("Zip complete");
})
.catch((err) => {
console.log(err);
});
};
deleteContentsOfDocumentDirectory() {
var path = RNFS.DocumentDirectoryPath;
var data = RNFS.readDir(path)
.then((results) => {
results.forEach(result => {
/* I assume each item here is a FILE */
RNFS.unlink(result.path)
.then(() => {
console.log("File Deleted");
})
.catch((err) => {
console.log(err.message);
});
});
});
};
copyFilesToDocumentDirectory(assets) {
var path = RNFS.DocumentDirectoryPath;
assets.forEach(asset => {
RNFS.exists(asset.uri)
.then((status) => {
if(status) {
var newPath = path "/" asset.fileName;;
console.log("Copying from: ", asset.uri, " -- to: ", newPath);
RNFS.copyFile(asset.uri, newPath);
};
});
});
};
storeToAWS()
this.deleteContentsOfDocumentDirectory();
this.copyFilesToDocumentDirectory(this.state.photoAssets);
this.copyFilesToDocumentDirectory(this.state.videoAssets);
this.zipDocumentDirectory();
};
// ... Render code etc;
};
Efforts:
I wrote the above because that was the problem I am trying to solve. I thought this could be solved by Promise
s but I am relatively new to the idea of promises/async/await. I tried adding Promise
s to each method to wait for them to finish; however, the functions still ran synchronously and the asynchronous tasks ran after. The output is below the code showing the Zipped
output inside zipDocumentDirectory()
occurs BEFORE the asynchronous commands inside copyFilesToDocumentDirectory()
.
import React, { Component } from 'react';
import { zip } from 'react-native-zip-archive';
import RNFS from 'react-native-fs';
export default class AddMedia extends React.Component {
state = {
photoAssets: [],
videoAssets: [],
videoThumbnails: [],
thumbnailReady: false
};
zipDocumentDirectory() {
var path = RNFS.DocumentDirectoryPath;
console.log("Zipped");
new Promise((resolve, reject) => {
zip(path, path "/urls.zip")
.then((path) => {
console.log("Zip complete");
resolve();
})
.catch((err) => {
console.log(err);
reject();
});
});
};
deleteContentsOfDocumentDirectory() {
var path = RNFS.DocumentDirectoryPath;
new Promise((resolve, reject) => {
var data = RNFS.readDir(path)
.then((results) => {
results.forEach(result => {
/* I assume each item here is a FILE */
RNFS.unlink(result.path)
.then(() => {
console.log("File Deleted");
resolve();
})
.catch((err) => {
console.log(err.message);
reject();
});
});
});
});
};
copyFilesToDocumentDirectory(assets) {
var path = RNFS.DocumentDirectoryPath;
assets.forEach(asset => {
new Promise((resolve, reject) => {
RNFS.exists(asset.uri)
.then((status) => {
if(status) {
var newPath = path "/" asset.fileName;;
console.log("Copying from: ", asset.uri, " -- to: ", newPath);
RNFS.copyFile(asset.uri, newPath);
resolve();
};
});
});
});
};
storeToAWS = async () => {
await this.deleteContentsOfDocumentDirectory();
await this.copyFilesToDocumentDirectory(this.state.photoAssets);
await this.copyFilesToDocumentDirectory(this.state.videoAssets);
// 2. Zip temporary folder storage (with encryption)
await this.zipDocumentDirectory();
OUTPUT:
LOG Zipped
LOG Copying from: XYZ/FEB964FB-3ABB-4CF7-A3B0-1E90BD1932C4.jpg -- to: XYZ/FEB964FB-3ABB-4CF7-A3B0-1E90BD1932C4.jpg
CodePudding user response:
I added missing returns. I hope it will work now
import React, { Component } from 'react';
import { zip } from 'react-native-zip-archive';
import RNFS from 'react-native-fs';
export default class AddMedia extends React.Component {
state = {
photoAssets: [],
videoAssets: [],
videoThumbnails: [],
thumbnailReady: false
};
zipDocumentDirectory() {
var path = RNFS.DocumentDirectoryPath;
console.log("Zipped");
return zip(path, path "/urls.zip")
.then((path) => {
console.log("Zip complete");
})
.catch((err) => {
console.log(err);
reject();
});
};
deleteContentsOfDocumentDirectory() {
var path = RNFS.DocumentDirectoryPath;
return RNFS.readDir(path)
.then((results) => {
return Promise.all(results.map(result => {
return RNFS.unlink(result.path)
.then(() => {
console.log("File Deleted");
})
.catch((err) => {
console.log(err.message);
});
}));
});
};
copyFilesToDocumentDirectory(assets) {
var path = RNFS.DocumentDirectoryPath;
return Promise.all(assets.map(asset => {
return RNFS.exists(asset.uri)
.then((status) => {
if(status) {
var newPath = path "/" asset.fileName;;
return RNFS.copyFile(asset.uri, newPath);
};
});
});
}));
};
storeToAWS = async () => {
await this.deleteContentsOfDocumentDirectory();
await this.copyFilesToDocumentDirectory(this.state.photoAssets);
await this.copyFilesToDocumentDirectory(this.state.videoAssets);
// 2. Zip temporary folder storage (with encryption)
await this.zipDocumentDirectory();
}
}
```