我试图一次又一次执行一次async
函数。但是问题在于它们正在一起执行。但是,我想要的是第二个执行必须在第一个执行完成之后开始。
PS,关于SO的问题很多,标题相同,例如JavaScript: execute async function one by one。但是他们都没有解决我的问题。
请检查Fiddle
$(document).ready(function() {
function typeWriter(element, msg, speed, index = 0) {
if (index < msg.length) {
$(element).html($(element).html() + msg.charAt(index++));
setTimeout(function() {
typeWriter(element, msg, speed, index);
}, speed);
}
}
$('.intro').fadeIn(function() {
const greet = new Promise(function(resolve, reject) {
typeWriter('#sayHello', "Hello !!", 200);
resolve();
});
greet.then(function() {
typeWriter('#myName', "I'm learning programming", 200);
});
});
});
.intro {
text-align: center;
display: none;
font-family: 'Amaranth', sans-serif;
}
.cursor {
display: inline-block;
width: 10px;
height: inherit !important;
}
.cursor>span {
display: inline-block;
position: relative;
top: 2px;
width: 3px;
height: 26px;
margin: 0 0 0 0px;
background-color: #000;
animation: blink 1s step-end infinite;
}
@keyframes blink {
from,
to {
opacity: 1;
}
50% {
opacity: 0;
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="intro">
<h1 class="title"><span id="sayHello"></span><span class="cursor"><span></span></span>
</h1>
<h1 class="title"><span id="myName"></span><span class="cursor"><span></span></span>
</h1>
</div>
在这里,我正在尝试在两个不同的print
标记中插入两行文本。为此,我要致电<h1>
两次,每个function typeWriter(...)
一次。我正在尝试<h1>
两行,上一行完成后进行一行,即在第一次调用中打印print
,完成后再在第二行中打印Hello !!
,但不是发生。问题是他们一起执行。
在进一步寻找解决方案时,我发现了这个问题JavaScript: execute async function one by one,并遵循@DavidHedlund给出的答案,但这对我不起作用。抱歉,如果我有任何错误。
请看一下我在@DavidHedlund答案中尝试过的小提琴。在这种情况下,仅打印I'm Learning Programming
。
Hello !!
$(document).ready(function() {
function typeWriter(element, msg, speed, index = 0) {
if (index < msg.length) {
$(element).html($(element).html() + msg.charAt(index++));
setTimeout(function() {
typeWriter(element, msg, speed, index);
}, speed);
}
}
$('.intro').fadeIn(function() {
function executeTasks() {
var tasks = Array.prototype.concat.apply([], arguments);
var task = tasks.shift();
task(function() {
if (tasks.length > 0)
executeTasks.apply(this, tasks);
});
}
function createTask(param) {
let element = param[0];
let msg = param[1];
let speed = param[2];
return function(callback) {
setTimeout(function() {
if (typeof callback == 'function') typeWriter(element, msg, speed);
}, 1);
}
}
var t1 = createTask(['#sayHello', "Hello !!", 200]);
var t2 = createTask(['#myName', "I'm Anshuman Gupta", 200]);
executeTasks(t1, t2);
});
});
.intro {
text-align: center;
display: none;
font-family: 'Amaranth', sans-serif;
}
.cursor {
display: inline-block;
width: 10px;
height: inherit !important;
}
.cursor>span {
display: inline-block;
position: relative;
top: 2px;
width: 3px;
height: 26px;
margin: 0 0 0 0px;
background-color: #000;
animation: blink 1s step-end infinite;
}
@keyframes blink {
from,
to {
opacity: 1;
}
50% {
opacity: 0;
}
}
谢谢!
答案 0 :(得分:1)
因此,这里发生的是typeWriter()
方法正在使用setTimeout()
,该方法适用于线程模型(即setTimeout()
不会阻塞线程,而是会立即返回)。因此,typeWriter()
方法立即返回,因此相应的promise得以解析。
尝试此代码
$(document).ready(function() {
function typeWriter(element, msg, speed) {
return new Promise (function (resolve, reject) {
var recursive = function (element, msg, speed, index) {
if (index < msg.length) {
$(element).html($(element).html() + msg.charAt(index++));
setTimeout(function() {
recursive(element, msg, speed, index);
}, speed)
} else {
resolve();
}
}
recursive(element, msg, speed, 0)
})
}
$('.intro').fadeIn(function() {
typeWriter('#sayHello', "Hello !!", 200).then(function() {
return typeWriter('#myName', "I'm learning programming", 200);
});
});
})
答案 1 :(得分:1)
或者,如果您觉得更简单,则可以使用await
。
$(document).ready(function() {
function typeWriter(element, msg, speed, index = 0) {
return new Promise((resolve, reject) => {
if (index < msg.length) {
$(element).html($(element).html() + msg.charAt(index++));
setTimeout(function() {
typeWriter(element, msg, speed, index).then(resolve).catch(reject);
}, speed);
} else {
resolve();
}
});
}
async function typeStuff() {
console.log("Hi");
await typeWriter('#sayHello', "Hello !!", 200);
await typeWriter('#myName', "I'm learning programming", 200);
}
$('.intro').fadeIn(function() {
typeStuff();
});
});
.intro {
text-align: center;
display: none;
font-family: 'Amaranth', sans-serif;
}
.cursor {
display: inline-block;
width: 10px;
height: inherit !important;
}
.cursor>span {
display: inline-block;
position: relative;
top: 2px;
width: 3px;
height: 26px;
margin: 0 0 0 0px;
background-color: #000;
animation: blink 1s step-end infinite;
}
@keyframes blink {
from,
to {
opacity: 1;
}
50% {
opacity: 0;
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="intro">
<h1 class="title"><span id="sayHello"></span><span class="cursor"><span></span></span>
</h1>
<h1 class="title"><span id="myName"></span><span class="cursor"><span></span></span>
</h1>
</div>
说明:在您的代码中,您在调用resolve
之后立即调用了typeWriter
。问题是typeWriter
不会“阻塞”,这意味着它将设置超时以在将来执行代码并立即返回。您可以避免这样做typeWriter
。然后,您可以使用await
(更干净,但浏览器支持较少)或typeWriter(...).then(function() { /* Do more stuff */ })
(它们实际上是等效的)。
答案 2 :(得分:1)
问题是您不等待递归函数完成然后调用resolve。
const greet = new Promise(function(resolve, reject) {
typeWriter('#sayHello', "Hello !!", 200);
resolve();
});
greet.then(function() {
typeWriter('#myName', "I'm learning programming", 200);
});
尝试一下:
const timeout = (speed) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve();
}, speed);
});
}
$(document).ready(function() {
async function typeWriter(element, msg, speed, index = 0) {
if (index < msg.length) {
$(element).html($(element).html() + msg.charAt(index++));
await timeout(speed);
await typeWriter(element, msg, speed, index);
}
}
$('.intro').fadeIn(function() {
const greet = new Promise(async function(resolve, reject) {
await typeWriter('#sayHello', "Hello !!", 200);
resolve();
});
greet.then(function() {
typeWriter('#myName', "I'm learning programming", 200);
});
});
});