我使用 Async/Await 编写了一个简短的脚本,该脚本在短间隔后逐个打印出字母。根据我所理解的情况,我尝试以多种方式重写代码,期望获得相同的结果,但我无法使这些替代方案中的任何一个起作用。特别是,我认为更改控制台.log((在代码中发生的位置会很简单。
这是原始工作代码:
const welcomeMessage = () => {
const message = 'hello'
const timer = [200,400,200,400,200,400];
// Promisify setTimeout() and feed in counter from sendMessage()
const setTimeoutPromise = num => {
return new Promise(resolve => {
setTimeout(resolve, timer[num]);
})
};
// Async/Await with a For loop calling setTimeoutPromise()
const sendMessage = async () => {
for (count = 0; count < message.length; count++) {
await setTimeoutPromise(count);
console.log(message[count]);
};
};
sendMessage();
}
welcomeMessage();
然后我尝试进行一些修改,但没有一个奏效。
Mdofication #1:在这个版本中,我认为我可以直接调用并运行 sendMessage(( 函数中的代码,而无需稍后调用它。但是,此修改后没有任何反应:
async () => { //No name and removed call to sendMessage() later in code
for (count = 0; count < message.length; count++) {
await setTimeoutPromise(count);
console.log(message[count]);
};
};
const welcomeMessage = () => {
const message = 'hello'
const timer = [200,400,200,400,200,400];
// Promisify setTimeout() and feed in counter from sendMessage()
const setTimeoutPromise = num => {
return new Promise(resolve => {
setTimeout(resolve, timer[num]);
})
};
async () => { //No name and removed call to sendMessage() later in code
for (count = 0; count < message.length; count++) {
await setTimeoutPromise(count);
console.log(message[count]);
};
};
}
welcomeMessage();
修改#2:我恢复了代码,然后尝试将console.log((函数移动到setTimeout((函数中,认为这将在每个循环中调用。无论是空的((还是将(解析(传递到setTimeout((,它都只打印了第一个字母。用(解析,num(它说未定义:
const setTimeoutPromise = num => {
return new Promise(resolve => {
setTimeout((resolve) => {
console.log(message[num]);
resolve;
}, timer[num]);
})
};
const sendMessage = async () => {
for (count = 0; count < message.length; count++) {
await setTimeoutPromise(count);
};
};
const welcomeMessage = () => {
const message = 'hello'
const timer = [200,400,200,400,200,400];
const setTimeoutPromise = num => {
return new Promise(resolve => {
setTimeout((resolve) => {
console.log(message[num]);
resolve;
}, timer[num]);
})
};
const sendMessage = async () => {
for (count = 0; count < message.length; count++) {
await setTimeoutPromise(count);
};
};
sendMessage();
}
welcomeMessage();
修改#3:最后,我尝试提前定义一个函数以传递给setTimeout((,该函数将用于处理"resolve"和console.log((。我尝试了一些变体,但似乎再次没有通过循环进行,因为 console.log(( 只被调用了一次。
// New function to handle resolve and the counter
function newFunction(func, num) {
console.log(message[num]);
func;
}
const setTimeoutPromise = num => {
return new Promise(resolve => {
setTimeout(newFunction(resolve, num), timer[num]);
})
};
const sendMessage = async () => {
for (count = 0; count < message.length; count++) {
await setTimeoutPromise(count);
};
};
const welcomeMessage = () => {
const message = 'hello'
const timer = [200,400,200,400,200,400];
// New function to handle resolve and the counter
function newFunction(func, num) {
console.log(message[num]);
func;
}
const setTimeoutPromise = num => {
return new Promise(resolve => {
setTimeout(newFunction(resolve, num), timer[num]);
})
};
const sendMessage = async () => {
for (count = 0; count < message.length; count++) {
await setTimeoutPromise(count);
};
};
sendMessage()
}
welcomeMessage();
在我看来,在你深入了解同步JavaScript的工作原理之前,你已经开始使用异步了。异步本身也足够难,所以结合起来,它让你完全困惑。
让我解释一下您的片段中发生了什么以及有什么问题。
让我们从工作开始。
该代码:
const setTimeoutPromise = num => {
return new Promise(resolve => {
setTimeout(resolve, timer[num]);
})
};
。创建一个名为setTimeoutPromise
的函数,该函数:
- 以索引(数字(作为其参数
- 返回一个承诺:
timer[num]
毫秒后- 解析为
undefined
(默认情况下,setTimeout
不会向其回调传递任何内容;在这种情况下,回调是resolve
函数(
下一部分:
const sendMessage = async () => {
for (count = 0; count < message.length; count++) {
await setTimeoutPromise(count);
console.log(message[count]);
};
};
。定义了一个名为sendMessage
的异步函数,它:
- 迭代
message
,对于每个字符:- 打电话给
setTimeoutPromise
并等待它返回的承诺 - 等待后,将当前字符记录到控制台
- 打电话给
最后
sendMessage();
。调用sendMessage
,并因此启动类型。
现在,让我们继续下一个片段。
此代码:
async () => { //No name and removed call to sendMessage() later in code
for (count = 0; count < message.length; count++) {
await setTimeoutPromise(count);
console.log(message[count]);
};
};
。创建一个异步函数,但它不会调用或将其分配给任何变量:只需丢弃它。
要修复此代码段,请立即调用该函数,方法是在它后面放置()
!
const welcomeMessage = () => {
const message = 'hello'
const timer = [200,400,200,400,200,400];
// Promisify setTimeout() and feed in counter from sendMessage()
const setTimeoutPromise = num => {
return new Promise(resolve => {
setTimeout(resolve, timer[num]);
})
};
(async () => { //No name and removed call to sendMessage() later in code
for (count = 0; count < message.length; count++) {
await setTimeoutPromise(count);
console.log(message[count]);
};
})(); //The () at the end calls it
}
welcomeMessage();
有问题的代码段 #2
这有两个问题:
const setTimeoutPromise = num => {
return new Promise(resolve => {
setTimeout((resolve) => { //Problem 1
console.log(message[num]);
resolve; //Problem 2
}, timer[num]);
})
};
您尝试从
setTimeout
中获取名为resolve
的参数,但正如我上面提到的,它不会传递任何参数。要解决它,请从
setTimeout((resolve) => {
中删除resolve
!由于词法范围,我们已经有了上面行的resolve
函数。你不调用
resolve
,这会让await
代码挂在第一个字母之后(承诺永远不会得到解决(。要修复它,请在
resolve
之后放()
!
const welcomeMessage = () => {
const message = 'hello'
const timer = [200,400,200,400,200,400];
const setTimeoutPromise = num => {
return new Promise(resolve => {
setTimeout(() => {
console.log(message[num]);
resolve();
}, timer[num]);
})
};
const sendMessage = async () => {
for (count = 0; count < message.length; count++) {
await setTimeoutPromise(count);
};
};
sendMessage();
}
welcomeMessage();
>有问题的片段 #3此代码中还有 2 个问题:
// New function to handle resolve and the counter
function newFunction(func, num) {
console.log(message[num]);
func; //Problem 1
}
const setTimeoutPromise = num => {
return new Promise(resolve => {
setTimeout(newFunction(resolve, num), timer[num]); //Problem 2
})
};
同上;
newFunction
不调用resolve
(名为fn
(。当您打算调用函数时,尽量不要忘记
()
这与问题 1 相反。你立即调用
newFunction
(由于它后面的括号:(resolve, num)
(,并将其返回值(undefined
(传递给setTimeout
。 如果没有问题 1,这将导致立即记录所有字母。在这种情况下,
setTimeout
通过删除该函数后面的(resolve, num)
来在内部调用该函数。为了将参数传递给它,setTimeout
接受额外的参数,它将移交给它的回调(在本例中为newFunction
(。
const welcomeMessage = () => {
const message = 'hello'
const timer = [200,400,200,400,200,400];
// New function to handle resolve and the counter
function newFunction(func, num) {
console.log(message[num]);
func();
}
const setTimeoutPromise = num => {
return new Promise(resolve => {
setTimeout(newFunction, timer[num], resolve, num);
})
};
const sendMessage = async () => {
for (count = 0; count < message.length; count++) {
await setTimeoutPromise(count);
};
};
sendMessage()
}
welcomeMessage();
<小时 />一起...
可以组合这些修复程序,以获得类似以下内容:
const welcomeMessage = () => {
const message = 'hello'
const timer = [200,400,200,400,200,400];
// New function to handle resolve and the counter
function newFunction(func, num) {
console.log(message[num]);
func();
}
const setTimeoutPromise = num => {
return new Promise(resolve => {
setTimeout(newFunction, timer[num], resolve, num);
})
};
(async () => {
for (count = 0; count < message.length; count++) {
await setTimeoutPromise(count);
};
})();
}
welcomeMessage();
<小时 />结论
使用括号(()
(调用函数,但避免使用括号将函数用作对象:将其传递给或分配给某些东西,获取或设置其属性等。