Full code: https://github.com/kenpeter/clip_to_music
Basically, this simple nodejs script should execute these actions in order
Rename all mp4 file, so no files containing no space.
Convert all mp4 to mp3
kill adb server (with child process exec)
start adb server (with child process exec)
push to my android phone
Some sample code:
renamePromise
.then(() => {
return musicPromise;
})
.then(() => {
return adbKillPromise;
})
.then(() => {
return adbStartPromise;
})
.then(() => {
return adbPushPromise;
})
.then(() => {
console.log('---- all done----');
process.exit(0);
});
The output is like this, out of order
; yarn start
yarn start v0.21.3
$ node clip_to_music.js
---adb kill---
-- Rename one file --
/home/kenpeter/Videos/4K Video Downloader/1.mp4
-- Rename one file --
/home/kenpeter/Videos/4K Video Downloader/2.mp4
--- rename all files done ---
adb push /var/www/html/test/testme/clip_to_music/audio/1.mp3 /sdcard/Music
adb push /var/www/html/test/testme/clip_to_music/audio/2.mp3 /sdcard/Music
---- done push all music ---
* daemon not running. starting it now on port 5037 *
* daemon started successfully *
---adb start---
single mp3 done!
single mp3 done!
--------- all mp3 conversion done --------
---- all done----
Done in 10.79s.
As you can see the output above, which is out of orders
Your code implies that you've already started the operations represented by musicPromise
, adbKillPromise
, adbStartPromise
and adbPushPromise
and you are running them all in flight at the same time. As such, they will finish in whatever order they naturally finish in and you have no direct control over that.
Remember a promise is merely a tool for monitoring an async operation. Since you already have the promise, you must have already started the async operation and thus your chain of promises does not control the order of the activities at all. It does control the order in which you process the results, but not the order of the activities themselves at all.
To truly sequence the operations themselves, you need to not start the succeeding operations until the ones you want to precede it are done more like this:
a().then(b).then(c).catch(err => { /* handler error here */});
Where a()
, b()
and c()
are functions that return a promise and each start their corresponding async operation.
As an example with one of your operations, change this:
// adb kill
var adbKillPromise = new Promise((resolve, reject) => {
exec("adb kill-server", (err, stdout, stderr) => {
if (err) {
console.error(err);
return;
}
console.log(stdout);
console.log('---adb kill---');
resolve();
});
});
to be a function that you can call later:
// adb kill
function adbKill() {
return new Promise((resolve, reject) => {
exec("adb kill-server", (err, stdout, stderr) => {
if (err) {
console.error(err);
reject(err);
return;
}
console.log(stdout);
console.log('---adb kill---');
resolve();
});
});
}
Note, that it is now a function that returns a promise so it can be called upon demand (only when it is time to call it) and I also added error handling to it so it rejects if there's an error.
And, do that for all the other variables you have defined that correspond to one of the async operations you want to sequence. Then, you can do this:
rename().then(music).then(adbKill).then(adbStart).then(adbPush).then(() => {
console.log('---- all done----');
process.exit(0);
}).catch(err => {
console.log('Error', err);
process.exit(1);
});