Why do we need Promise in JavaScript

  1. 1.Cleaner code and avoid callback hell
  2. 2.Backbones of some new features
  3. 3.Automatic error handling

1.Cleaner code and avoid callback hell

Using callbacks:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
function get(url, callback) {
var request = new XMLHttpRequest();
request.open('GET', url);
request.onload = function() {
if (request.readyState === 4) {
if (request.status === 200) {
callback(null, request.responseText);
} else {
callback(request.statusText, null);
}
}
};
request.onerror = function(e) {
callback(e.type, null)
};
request.send();
}

get('./file1.txt', function(error, text) {
if (error) {
//alert('Error: ' + error);
} else {
get('./file2.txt', function(err, text2) {
if (err) {
//alert('Error2: ' + err);
} else {
showContents(text, text2);
}
});
}
});

function showContents(text1, text2) {
console.log('text1:', text1);
console.log('text2:', text2);
}

Using promises:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// Wrap the request in a promise
function get(url) {
return new Promise((resolve, reject) => {
var request = new XMLHttpRequest();
request.open('GET', url);
request.onload = function() {
if (request.readyState === 4) {
if (request.status === 200) {
resolve(request.responseText);
} else {
reject(request.statusText);
}
}
};
request.onerror = function(e) {
reject(e.type, null)
};
request.send();
});
}

let text1 = '';
get('./file1.txt')
.then(text => text1 = text) // Save the first file content to a variable
.then(() => get('./file2.txt')) // A new promise object is expected, so we return it
.then(text=> showContents(text1, text)) // The second file content as the fulfillment value

2.Backbones of some new features

Many APIs are promise-based:

  • Fetch API
  • MediaDevices API
  • RTCPeerConnection
  • Async functions
  • Element API: requestFullscreen
  • Document API: exitFullscreen
  • HTMLMediaElement API: play
  • OfflineAudioContext API: startRendering
  • BaseAudioContext API: decodeAudioData

3.Automatic error handling

Using callbacks:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
get('./file1.txt', function(error, text) {
if (error) {
handleFileError(error); // first
} else {
get('./file2.txt', function(err, text2) {
if (err) {
handleFileError(err); // second
} else {
showContents(text, text2);
}
});
}
});

function handleFileError(err) {
alert('File Error: ' + err);
}

Using promises, errors will be passed down the chain, so we can handle it in one common place without having to write it twice.

1
2
3
4
5
6
let text1 = '';
get('./file1.txt')
.then(text => text1 = text)
.then(() => get('./file2.txt'))
.then(text=> showContents(text1, text))
.catch(handleFileError) // Write only once