Javascript Promises
var output = '';
var errorLog = '';
function task(msg, msec){
output += msg;
return new Promise((resolve, reject)=>{
setTimeout(()=>{
const error = true;
!error ? resolve()
: reject( 'Error-task-' + msg)
}, msec);
});
}
task('task1->', 30)
.then( task('task2->', 10)
.then(task('task3->', 0)
.then(display)
.catch(err => errorLog += err))
.catch(err => errorLog += err))
.catch(err => errorLog += err)
.finally( () => {display(); displayErrorLog();})
function display(){
console.log('output: ' + output);
}
function displayErrorLog(){
console.log('ErrorLog: ' + errorLog);
}
lets refactor the previos sample of list post, now with promise
const posts = [{title: 'post one', body: 'body of post one'},
{title: 'post two', body: 'body of post two'}];
function getPosts(){
setTimeout(() => {
let output = '';
posts.forEach( (post, index) => {
console.log(index + ' ' + post.title );
output += `<li>${post.title}</li>`;
});
document.body.innerHTML = output;
}, 100);
};
function createPost(post){
return new Promise((resolve, reject) => {
setTimeout(() => {
posts.push(post);
const error = false;
!error ? resolve()
: reject('Error: something went wrong');
}, 200);
});
};
createPost({title: 'post three', body:'body of post three'})
.then( getPosts)
.catch( err => console.log(err));
Another sample, In this case the procedure task put the main procedure of output buffer inside the async function, so the output spected is in disorder defined by the timeout of the procedures because all are executed asynchronously, That´s because the process of buffer output must be out and before the setTimeout (asynchrous process).
var output = '';
function task(msg, msec){
return new Promise((resolve, reject)=>{
setTimeout(()=>{
output += msg;
const error = false;
!error ? resolve()
: reject( 'Error - task - ' + msg)
}, msec);
});
}
task('task1->', 30)
.then( task2('task2->', 10)
.then(task('task3->', 50)
.then(display)))
function display(){
console.log(output);
}
// output: task2->task1->task3->
Putting the process of buffer output before the asynchronous process (setTimeout), So the execution order of the task are executed as expected independently of the taken time for each of them.
var output = '';
function task(msg, msec){
output += msg;
return new Promise((resolve, reject)=>{
setTimeout(()=>{
const error = false;
!error ? resolve()
: reject( 'Error - task - ' + msg)
}, msec);
});
}
task('task1->', 30)
.then( task('task2->', 10)
.then(task('task3->', 0)
.then(display)))
function display(){
console.log(output);
}
// output: task1->task2->task3-
Adding the catch management for the promises, forcing to fail to see the catch, look the order of the error messages, first the task3 then task2 and finally task1
var output = '';
function task(msg, msec){
output += msg;
return new Promise((resolve, reject)=>{
setTimeout(()=>{
const error = true;
!error ? resolve()
: reject( 'Error - task - ' + msg)
}, msec);
});
}
task('task1->', 30)
.then( task('task2->', 10)
.then(task('task3->', 0)
.then(display)
.catch(err => console.log(err)))
.catch(err => console.log(err)))
.catch(err => console.log(err))
function display(){
console.log(output);
}
// output: Error - task - task3->
// Error - task - task2->
// Error - task - task1->
Let´s separate the error log buffer display in order to manage the flow.
The output is ErrorLog with the buffer error empty, why? because the displayErrorLog() is executed asynchronous before all the other process.
var output = '';
var errorLog = '';
function task(msg, msec){
output += msg;
return new Promise((resolve, reject)=>{
setTimeout(()=>{
const error = true;
!error ? resolve()
: reject( 'Error-task-' + msg)
}, msec);
});
}
task('task1->', 30)
.then( task('task2->', 10)
.then(task('task3->', 0)
.then(display)
.catch(err => errorLog += err))
.catch(err => errorLog += err))
.catch(err => errorLog += err)
displayErrorLog();
function display(){
console.log('output: ' + output);
}
displayErrorLog();
function displayErrorLog(){
console.log('ErrorLog: ' + errorLog);
}
// output: ErrorLog:
To check the error log delay the execution of the displayErrorLog function
...
task('task1->', 30)
.then( task('task2->', 10)
.then(task('task3->', 0)
.then(display)
.catch(err => errorLog += err))
.catch(err => errorLog += err))
.catch(err => errorLog += err)
displayErrorLog();
function display(){
console.log('output: ' + output);
}
displayErrorLog();
function displayErrorLog(){
setTimeout(()=>{
console.log('ErrorLog: ' + errorLog);
}, 40);
}
// output: ErrorLog: Error-task-task3->Error-task-task2->Error-task-task1->
Or integrate into the build task pattern, this way the displayErrorLog will be secuenciated synchronous into the flow process. notice that .then(displayErrorLog) is not properly used, because .then is executed on resolve situation.
task('task1->', 30)
.then( task('task2->', 10)
.then(task('task3->', 0)
.then(display)
.catch(err => errorLog += err))
.catch(err => errorLog += err))
.catch(err => errorLog += err)
.then(displayErrorLog)
function display(){
console.log('output: ' + output);
}
displayErrorLog();
function displayErrorLog(){
console.log('ErrorLog: ' + errorLog);
}
// output: ErrorLog: Error-task-task3->Error-task-task2->Error-task-task1->
Use displayErrorLog into the last .catch to see all the error buffer log.
...
task('task1->', 30)
.then( task('task2->', 10)
.then(task('task3->', 0)
.then(display)
.catch(err => errorLog += err))
.catch(err => errorLog += err))
.catch(err => {errorLog += err; displayErrorLog();})
.finally To show the buffers at the end of the secuence use .finally
...
task('task1->', 30)
.then( task('task2->', 10)
.then(task('task3->', 0)
.then(display)
.catch(err => errorLog += err))
.catch(err => errorLog += err))
.catch(err => errorLog += err)
.finally( () => {display(); displayErrorLog();})
// output: output: task1->task2->task3->
// ErrorLog: Error-task-task3->Error-task-task2->Error-task-task1->
Sample with callbacks
const userLeft = false
const userWatchingCatMeme = true
function watchTutorialCallback(callback, errorCallback){
if(userLeft){
errorCallback({
name: 'User left',
message: ':('
})
} else if (userWatchingCatMeme) {
errorCallback({
name: 'User Watching Cat Meme',
message: 'message error watching cat meme'
})
} else {
callback('Thanks and Subscribe')
}
}
watchTutorialCallback((message) =>{
console.log('Success: ' + message)
}, (error) => {
console.log(error.name + ' ' + error.message)
})
Success: Thanks and Subscribe
Same but with promise
const userLeft = false
const userWatchingCatMeme = false
function watchTutorialPromise(){
return new Promise((resolve, reject) => {
if (userLeft){
reject({
name: 'User left',
message: ':('
})
} else if (userWatchingCatMeme) {
reject({
name: 'User Watching Cat Meme',
message: 'message error watching cat meme'
})
} else {
resolve('Thanks and Subscribe')
}
});
}
watchTutorialPromise().then((message) => {
console.log('Success: ' + message)
}).catch((error) => {
console.log(error.name + ' ' + error.message)
})
Promise.All
const taskOne = new Promise((resolve,reject) => {
resolve('task1->')
})
const taskTwo = new Promise((resolve,reject) => {
resolve('task2->')
})
const taskThree = new Promise((resolve,reject) => {
resolve('task3->')
})
Promise.all([
taskOne, taskTwo, taskThree
]).then((message) => {
console.log( message)
})
//output: Array(3) [ "task1->", "task2->", "task3->" ]
Setting different process time
const taskOne = new Promise((resolve,reject) => {
setTimeout(() => {
resolve('task1->')
}, 2000)
})
const taskTwo = new Promise((resolve,reject) => {
setTimeout(() => {
resolve('task2->')
}, 30)
})
const taskThree = new Promise((resolve,reject) => {
setTimeout(() => {
resolve('task3->')
}, 10)
})
Promise.all([
taskOne, taskTwo, taskThree
]).then((message) => {
console.log( message)
})
//output: Array(3) [ "task1->", "task2->", "task3->" ]
Promise.race
const taskOne = new Promise((resolve,reject) => {
setTimeout(() => {
resolve('task1->')
}, 2000)
})
const taskTwo = new Promise((resolve,reject) => {
setTimeout(() => {
resolve('task2->')
}, 30)
})
const taskThree = new Promise((resolve,reject) => {
setTimeout(() => {
resolve('task3->')
}, 10)
})
Promise.race([
taskOne, taskTwo, taskThree
]).then((message) => {
console.log( message)
})
//output: task3->
Promise All with fetch json
const promise1 = Promise.resolve("promise1 resolved")
const promise2 = 10;
const promise3 = new Promise((resolve,reject) =>
setTimeout(resolve, 100, 'promise3'))
const promise4 = fetch('https://jsonplaceholder.typicode.com/users')
.then(val => val.json())
Promise.all([ promise1, promise2, promise3, promise4])
.then(value => console.log(value))
Browser Inspector Output
Array(4) [ "promise1 resolved", 10, "promise3", (10) […] ]
0: "promise1 resolved"
1: 10
2: "promise3"
3: Array(10) [ {…}, {…}, {…}, … ]
0: Object { id: 1, name: "Leanne Graham", username: "Bret", … }
1: Object { id: 2, name: "Ervin Howell", username: "Antonette", … }
2: Object { id: 3, name: "Clementine Bauch", username: "Samantha", … }
3: Object { id: 4, name: "Patricia Lebsack", username: "Karianne", … }
4: Object { id: 5, name: "Chelsey Dietrich", username: "Kamren", … }
5: Object { id: 6, name: "Mrs. Dennis Schulist", username: "Leopoldo_Corkery", … }
6: Object { id: 7, name: "Kurtis Weissnat", username: "Elwyn.Skiles", … }
7: Object { id: 8, name: "Nicholas Runolfsdottir V", username: "Maxime_Nienow", … }
8: Object { id: 9, name: "Glenna Reichert", username: "Delphine", … }
9: Object { id: 10, name: "Clementina DuBuque", username: "Moriah.Stanton", … }
length: 10
<prototype>: Array []
length: 4
<prototype>: Array []
eot
No hay comentarios:
Publicar un comentario