Reputation: 4152
In order to better understand Promise syntax, I'm trying to convert the following pseudo-code into modern JavaScript.
Here's the old code, featuring the infamous callback hell:
var floppy = require( 'floppy' );
floppy.load( 'disk1', function( data1 ) {
floppy.prompt( ' Please insert disk 2', function() {
floppy.load( 'disk2', function( data2 ) {
floppy.prompt( ' Please insert disk 3', function() {
floppy.load( 'disk3', function( data3 ) {
floppy.prompt( 'Please insert disk 4', function() {
// If Node.js would've existed in 1995.
} );
} );
} );
} );
} );
} );
Please help me convert the above into JavaScript with Promise syntax (no async/await). I'm a Promise newbie, but here's what I came up with. Is the syntax, nesting and functionality the same as the above code? If not, please help me convert the callback madness into nice JavaScript with Promises.
const floppy = require( 'floppy' );
floppy.load( 'disk1' )
.then( data1 => {
floppy.prompt( 'Please insert disk 2' );
} )
.then(
floppy.load( 'disk2' )
)
.then( data2 => {
floppy.prompt( 'Please insert disk 3' );
} )
.then(
floppy.load( 'disk3' )
)
.then( data3 => {
floppy.prompt( 'Please insert disk 4' );
} )
.then(
// Node.js using Promises avoids callback hell!
);
Upvotes: 0
Views: 91
Reputation: 19288
First monkeypatch your floppy
object with the following methods:
floppy.loadAsync = function(d) {
return new Promise(resolve => {
floppy.load(d, resolve);
});
};
floppy.PromptAsync = function(message) {
return new Promise(resolve => {
floppy.load(message, resolve);
});
};
Now you can write:
floppy.loadAsync('disk1')
.then(data1 => floppy.promptAsync(' Please insert disk 2'))
.then(() => floppy.loadAsync('disk2'))
.then(data2 => floppy.promptAsync(' Please insert disk 3'))
.then(() => floppy.loadAsync('disk3'))
.then(data3 => floppy.promptAsync(' Please insert disk 4'));
If, as seems likely, you want to access data1
, data2
, data3
, and data4
in the final callback, then you have a range of options available to you.
For example, with the "Break the Chain" approach, you might write:
var promise1a = floppy.loadAsync('disk1');
var promise1b = promise1a.then((data1) => floppy.promptAsync(' Please insert disk 2'));
var promise2a = promise1b.then(() => floppy.loadAsync('disk2'));
var promise2b = promise2a.then((data2) => floppy.promptAsync(' Please insert disk 3'));
var promise3a = promise2b.then(() => floppy.loadAsync('disk3'));
var promise3b = promise3a.then((data3) => floppy.promptAsync(' Please insert disk 4'));
var promise4a = promise3b.then(() => floppy.loadAsync('disk4'));
Promise.all([promise1a, promise2a, promise3a, promise4a]).then((data) => {
var data1 = data[0];
var data2 = data[1];
var data3 = data[2];
var data4 = data[3];
});
Upvotes: 2
Reputation: 23379
Async would be much cleaner.
Write a wrapper function to convert the callback syntax to a promise.
const bigFloppyLoad = disk => new Promise(done => floppy.load(disk1, done));
Then I guess you need one for the prompt too...
const bigFloppyPrompt = message => new Promise(done => floppy.prompt(message, done));
Then you can run them in an async
block.
(async ()=>{
const data1 = await bigFloppyLoad('disk1');
await bigFloppyPrompt("Insert disk 2");
const data2 = await bigFloppyLoad('disk2');
await bigFloppyPrompt("Insert disk 3");
// ... and so forth
})();
Upvotes: 1