2016-03-13 3 views
0

Я добавил функцию в свой проект, который выводит предложения с таймаутом между символами, который отлично работает. Проблема в том, что JS выполняет все вызовы функций async, в то время как я хочу, чтобы он дождался завершения предыдущего предложения до следующего запуска.Ожидание выполнения предыдущей функции async

Я хочу, чтобы это была цельная функция jQuery, которая в конечном итоге работает с .delay. У меня есть довольно много предложений, которые я хочу напечатать, так что вложенные обратные вызовы будут утомительными.

Я пробовал несколько методов, но ближайший у меня есть вызов функции с задержкой между ними, что становится довольно раздражающим, когда мне нужно, чтобы функция завершилась.

Heres самая последняя

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

Тогда я должен называть их как этот

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

+1

что остановило вас от используя обратные вызовы? –

ответ

2

Рабочий пример с использованием нативного ES6 Promise и цепочки: https://jsfiddle.net/5hro5zq1/

var printMsg = function(msg) { 
    var promise = new Promise(function(resolve, reject){ 
    var index = 0; 
    var out = $('#out').append('<pre></pre>'); 
    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); 

Если вы идете на что-то вроде этого вы, вероятно, хотите использовать JQuery обещает или по крайней мере использовать polyfill: https://github.com/stefanpenner/es6-promise

2

Использование рекурсивной функции будет лучший choice.you будет больше контроль над выполнением с этим. Поскольку вы можете выполнить следующую функцию только после завершения текущей функции, используя код, как показано ниже.

var msg = [ 
 
    '1 Lorem ipsum Laboris Duis cupidatat ut id enim nisi', 
 
    '2 Lorem ipsum Laboris Duis cupidatat ut id enim nisi', 
 
    '3 Lorem ipsum Laboris Duis cupidatat ut id enim nisi', 
 
    '4 Lorem ipsum Laboris Duis cupidatat ut id enim nisi' 
 
]; 
 

 
var printMsg = function(index, callback) { 
 

 
    if (msg.length > index) { // if all messages are not yet loaded. 
 
    var out = $('#out').append('<pre></pre>'); 
 
    var charIndex = 0; 
 
    var interval = setInterval(function() { 
 
     out.children(':last-child').append(msg[index][charIndex++]); 
 
     if (charIndex >= msg[index].length) { 
 
     clearInterval(interval); 
 
     // resolve(); 
 
     printMsg(++index, callback); //increment the index and pass the same callback 
 
     //Recursive function call. 
 
     } 
 
    }, 150); 
 
    } else { 
 
    callback(); // all the messages are loaded 
 
    } 
 

 
} 
 

 
//trigger the chain reaction by passing the first message index 
 
printMsg(0, function() { 
 
    alert('all the messages are printed!! and Synchronously too'); 
 
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 

 
<div id="out"> 
 
    <div>

Примечание: Обратный вызов не имеет никакого использования в указанном выше растворе. Он используется только для передачи пользовательской функции при загрузке сообщений. Если функция printMsg используется во многих местах, это лучший подход. Возможно, вам придется поставить логику в другую часть printMsg.

+0

Спасибо, но мне нужно распечатать каждого символа с таймаутом между ними – Intern

+1

Вы можете поместить таймаут внутри printMsg правильно? как обертывание всей логики в интервал –

+0

@Intern Проверьте мой обновленный ответ. У него есть отсрочка в 2 секунды между каждой печатью сообщения. –