Monday, 9 January 2017

javascript - Waiting for previous async function to complete




I have added a function to my project that outputs sentences with a timeout between the characters, which works fine. The problem is that JS executes all the function calls async, while I want it to wait for the previous sentence to complete before the next one starts.



I want this to be a chainable jQuery function that works with .delay eventually. I have quite a few sentences that I want to print so nesting callbacks would be tedious.



I have tried a number of methods, but the closest I've got is calling the function with a delay between each one, which gets pretty annoying when I have to time the function to finish.



Heres the most recent




var printMsg = function(msg) {
var index = 0;
var out = $('#out').append('
');
var msgOut = setInterval(function() {
out.children(':last-child').append(msg[index++]);
if (index >= msg.length) {
clearInterval(msgOut);
};
}, 150);

}


Then I have to call them like this



var timeout = 8000;
printMsg('Lorem ipsum Laboris Duis cupidatat ut id enim nisi');
setTimeout(function() {
printMsg('Lorem ipsum Laboris Duis cupidatat ut id enim nisi');
}, timeout);

timeout += 8000;
setTimeout(function() {
printMsg('Lorem ipsum Laboris Duis cupidatat ut id enim nisi');
}, timeout);


Fiddle


Answer



Working example using native ES6 Promise and chaining: https://jsfiddle.net/5hro5zq1/




var printMsg = function(msg) {
var promise = new Promise(function(resolve, reject){
var index = 0;
var out = $('#out').append('
');
var msgOut = setInterval(function() {
out.children(':last-child').append(msg[index++]);
if (index >= msg.length) {
clearInterval(msgOut);
resolve();
};

}, 150);
});
return promise;
}

function printMessages(messages){
if(messages.length){
printMsg(messages[0])
.then(function(){
printMessages(messages.slice(1, messages.length))

});
}
}

var messages = [
'This is the first sentence.',
'This is another sentence.',
'We can do this all day long...'
];


printMessages(messages);


If you go for something like this you probably want to use jQuery promises or at least use the polyfill: https://github.com/stefanpenner/es6-promise


No comments:

Post a Comment

c++ - Does curly brackets matter for empty constructor?

Those brackets declare an empty, inline constructor. In that case, with them, the constructor does exist, it merely does nothing more than t...