setTimeout和Async await有什么区别?

4

我大致了解每个函数的作用。setTimeout是一个方法,可以在指定的毫秒数后调用函数或计算表达式。 Async/await返回一个Promise,并且只是一个可以被放置在队列中并且稍后可以检查函数结果的函数。

但两者都允许我 "延迟代码",它们都是异步函数。那么何时使用其中之一而不是另一个呢?

感谢任何帮助!


1
await通常会等待代码执行完毕。而settimeout则是等待一段时间后再执行代码。 - Sagar V
1
不,它们不一样。第一个允许您在稍后的某个时间安排代码执行。另一个允许您暂停异步代码路径(仅限异步代码路径),直到 Promise 已解决。 - Mike 'Pomax' Kamermans
5个回答

5

它们完全不同。

使用 async/await 可以让你在你的代码中扁平化地消费 Promises,而不需要嵌套回调或难以阅读的 .then 链。例如:

const doSomething = async () => {
  await asyncStep1();
  await asyncStep2();
  await asyncStep3();
};

每个异步步骤都返回一个 Promise。

await只有在你已经有一个 Promise 可以使用(或者你将其转换为 Promise)时,才允许你“延迟”代码块中的代码。

setTimeoutasync/await完全不相似 - setTimeout不消耗 Promise,也与 Promise 没有任何关系。 setTimeout允许您在之后排队回调函数,在超时时间结束后再调用该函数。

await 不同,setTimeout 不会延迟代码块中的代码 - 相反,您需要传递给它一个 回调函数,并且该回调函数稍后会被调用。


我看到他们返回的结果可能会有所不同。那么什么情况下需要使用async await呢?当您执行某些较耗时的操作,又不想等待它完成才运行其余代码时,使用async await是否更合适?而setTimeout则是在有意延迟执行某项任务的情况下使用,这个理解对吗?抱歉,我刚开始学习这些内容。 - Ikura
1
@Oci 当你有一个返回 Promise 的 API 并且想要以平铺的方式在代码中使用时,你可以使用 async/await。当你想要将某些操作排队到稍后执行时,你可以使用 setTimeout - CertainPerformance

3

很棒的问题。

你说得没错,它们都是异步代码。

简单回答两者之间的区别是:如果你正在执行这样的操作:

const fetchUser = async () => {
    const result = await fetch("/user");
    return await result.json();  
} 

async main1() {
    setTimeout(() => console.log("done", 2000)); 
}

async main2() {
    await fetchUser(); 
    console.log("done"); 
}

如果您没有在其他地方阻塞线程,那么setTimeout总是需要大约2000毫秒后才能记录“done”。fetchUser将在API完成时记录“done”,可能是100毫秒,也可能是10000毫秒。

但差异要多一些:

这部分与回调式代码或Promise式代码的差异有关。

回调式编码是较旧的编码方式,这里的差异不仅仅是如此。

让我们暂时放下setTimeout,谈论一下可能进行fetch调用的两种方式。

const fetchUserOne = async() => {
  const result = await fetch('https://jsonplaceholder.typicode.com/todos/1');
  const json = await result.json();
  return json;

}

const fetchUserTwo = () => {
  return fetch('https://jsonplaceholder.typicode.com/todos/2')
    .then(response => response.json())
};


async function main() {
  const result1 = fetchUserOne(); 
  const result2 = fetchUserTwo();
  
  console.log(result1);
  console.log(result2)
  
  const awaitedResult1 = await result1; 
  const awaitedResult2 = await result2; 
  
  console.log(awaitedResult1); 
  console.log(awaitedResult2); 

  
}

main().then(console.log("complete"));

现在我想要强调的是,尽管第二个例子使用了回调函数的风格,但是它们都使用了Promise

当你运行这段代码(并按下F12查看完整对象)时,你会注意到result1result2的日志信息是Promises。

Window.setTimeout没有使用Promise。

const result = setTimeout(() => {
  console.log("done");
}, 2000);

console.log(result);

setTimeout 的返回值是一个数字,可以用来取消超时。 这就带来了主要的区别:Promise 不可取消,而 setTimeout 可以。 查看这个有关取消 Promise 的 Stack Overflow 问题。 为了举例说明,让我们修改上面的示例。

const fetchUser = async () => {
    const result = await fetch("https://jsonplaceholder.typicode.com/todos/1");
    return await result.json();  
} 


let timeout; 

async function main1() {
    console.log("start main1"); 
    timeout = setTimeout(() => console.log("done timeout"), 2000); 
}

async function main2() {
    console.log("start main2"); 
    await fetchUser(); 
    console.log("done fetchuser"); 
}


main1(); 
main2(); 

clearTimeout(timeout); 

从上面可以看出,我们可以很容易地终止超时调用,但我们无法直接取消一个promise。

这并不意味着您不能取消该fetch请求,如您在此线程中看到的,但您不能直接取消promise本身。


2
首先,setTimeout是一个静态计时器,其时间取决于给定的时间。而async await则不同,它会等待被等待的函数或承诺返回任何responseerror
其次,您可以Timeout任何执行,但不能等待任何函数。
这里是官方文档Async await

2

setTimeout函数可以让你延迟执行一个操作。

它会在大约指定的时间之后执行该操作。请注意,这里是“大约”,因为实际上可能会有少量误差。

let log = () => console.log('log');

// invokes `log()` after a delay
setTimeout(log, 1000);

< p > async/await 可以帮助你处理承诺,而不需要函数处理程序; 它只是语法糖。它实际上不会延迟执行。

let promise = Promise.resolve(5);

let main = async() => {
  // without await
  promise.then(value => console.log(value));
  
  // with await
  console.log(await promise);
};

main();


后续问题,那么将async与setTimeout结合起来会变得毫无意义吗? - Ikura
@Oci 取决于你想要实现什么。 - Sagar V

0

虽然看起来相似,但 async await 和 setTimeout 并不相同。 如果你是 JavaScript 的新手,可以将 setTimeout 看作一个计时器,因此无论传递给 setTimeout 的代码块或函数是什么,它都会在固定时间后执行,它基本上延迟了代码的执行。而另一方面,async await 不绑定任何计时器,简单地说,使用 async await 的函数或 Promise 将等待函数或 Promise 返回适当的响应...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接