JavaScript Async/Await:尝试修改工作代码时失败



我使用 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]);
})
};
  1. 您尝试从setTimeout中获取名为resolve的参数,但正如我上面提到的,它不会传递任何参数。

    要解决它,请从setTimeout((resolve) => {中删除resolve!由于词法范围,我们已经有了上面行的resolve函数。

  2. 你不调用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
})
};
  1. 同上;newFunction不调用resolve(名为fn(。

    当您打算调用函数时,尽量不要忘记()

  2. 这与问题 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();

<小时 />

结论

使用括号(()(调用函数,但避免使用括号将函数用作对象:将其传递给或分配给某些东西,获取或设置其属性等。

最新更新