what's the point of wrapping promise into setTimer() and not?

huangapple go评论73阅读模式
英文:

what's the point of wrapping promise into setTimer() and not?

问题

Here's the translated code portion:

没有 setTimeout()  Promise

console.log('Promise 开始');
const lotteryPromise = new Promise(function (resolve, reject) {
   if (Math.random() >= 0.5) {
      resolve('你中了彩票');
   } else {
      reject(new Error('你输了钱'));
   }
});

lotteryPromise.then(res => console.log(res)).catch(err => console.error(err));
console.log('Promise 结束');

带有 setTimeout()  Promise

console.log('Promise 开始');
const lotteryPromise = new Promise(function (resolve, reject) {
    setTimeout(() => {
       if (Math.random() >= 0.5) {
          resolve('你中了彩票');
       } else {
          reject(new Error('你输了钱'));
       }
    }, 2000);
});

lotteryPromise.then(res => console.log(res)).catch(err => console.error(err));
console.log('Promise 结束');

我不理解包装在 Promise 中的 setTimeout() 的用法即使没有 setTimeout()Promise 也会异步执行对吗 setTimeout() 只是延迟代码执行还有其他我漏掉的东西吗顺便说一下我知道调用栈微任务和回调队列是如何工作的

If you have any more questions or need further assistance, feel free to ask.

英文:

promise with no setTimeout()
<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

console.log(&#39;Prmoise start&#39;);
const lotteryPromise = new Promise(function (resolve, reject) {
   if(Math.random() &gt;= 0.5) {
      resolve(&#39;You won the lottery&#39;);
   } else {
      reject(new Error(&#39;You lost your money&#39;));
   }
});
 
lotteryPromise.then(res =&gt; console.log(res)).catch(err =&gt; console.error(err));
console.log(&#39;Promise end&#39;);

<!-- end snippet -->

promise with setTimeout()

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

    console.log(&#39;Prmoise start&#39;);
    const lotteryPromise = new Promise(function (resolve, reject) {
    setTimeout( () =&gt; {
       if(Math.random() &gt;= 0.5) {
          resolve(&#39;You won the lottery&#39;);
       } else {
          reject(new Error(&#39;You lost your money&#39;));
       }
       },2000);
    });
     
    lotteryPromise.then(res =&gt; console.log(res)).catch(err =&gt; console.error(err));
    console.log(&#39;Promise end&#39;);

<!-- end snippet -->

I don't understand the usage of setTimeout() wrap in promise? Even without the setTimeout() wapping the promise is gettitng executing asynchronously right i.e it is added to eventQueue ? Is that SetTimeout is just delaying the code execution or Is there anything else I am missing? By the way I know how call stack, micro tasks and callback queue works....

答案1

得分: 3

你正在反向解决这个问题。你应该问:在没有 setTimeout 的情况下使用 promise 的目的是什么?

Promise 的目的是以标准方式管理异步代码。

new Promise 构造函数的目的是为不原生支持 promise 的异步代码创建一个 promise。

在你的第一部分代码中,传递给 Promise() 的函数没有任何异步操作。这是一个没有意义的 promise。

在你的第二部分代码中,setTimeout 是异步的,但你无法知道它何时完成(除非修改传递给它的回调函数)。使用 new Promise 允许你使用 promise 对象在 setTimeout 完成时执行某些操作。

话虽如此,没有明显的理由在这个示例中使用 setTimeout 或 promise。这完全是为了演示 promise 的工作原理,而不是演示何时 应该 使用 promise 或超时的实际示例。

英文:

You're addressing this problem backwards. You should be asking: What is the point of using a promise without setTimeout?

The purpose of a promise is to manage asynchronous code in a standard way.

The purpose of the new Promise constructor is to create a promise for asynchronous code which doesn't use promises natively.


In your first chunk of code, there is nothing asynchronous about the function you pass to Promise(). It's a pointless promise.

In your second chunk of code, the setTimeout is asynchronous but you've no way to know when it is finished (other than modifying the callback you pass to it). Using new Promise with it allows you to use the promise object to do something when the setTimeout is complete.

That said, there's no obvious reason to use setTimeout or promises at all for this example. It's entirely contrived to demonstrate how promises work, not to be a practical example of when you should use a promise or a timeout.

答案2

得分: 2

A slight miss conception of promises, is that there async. But there really only just a contract, that is then placed into a queue that will get processed before the next event loop. Very useful for writing async code, much nicer than callbacks.

以下是一个简单的示例,其中有2个承诺,其中1个承诺没有进行任何异步操作,另一个正在进行简单的异步休眠。这个异步休眠非常重要,因为它允许浏览器处理下一个事件循环。如果您去掉这个休眠,然后重新运行,看看浏览器会如何挂起。

> 请注意:当您注释掉 await sleep(1) 时,请准备使用 Chrome 的任务管理器来关闭浏览器标签页。

在上面的示例中,如果删除了那个休眠,为什么会导致浏览器挂起可能会看起来很奇怪。

浏览器使用一种称为事件循环的东西,它负责获取诸如鼠标点击、定时器等事件,并将它们分派给侦听器。这与协作式多任务操作系统的工作方式非常相似,类似于 Windows 3.11。

因此,在浏览器标签页内将运行一个事件循环,类似于以下内容:

while (running) {
  var message = getNextMessage();
  dispatchMessage(message);
}

上面的 getNextMessage 将高效地等待某个事件、定时器、鼠标移动等。因此,它不会浪费 CPU 资源,尽管它在这个紧凑的循环中。

那么这与承诺有什么关系呢?嗯,这就是 microtask 起作用的地方,不像 macrotask(例如定时器),浏览器可以从中分派,它们基本上被放入一个队列中,在下一个 macrotask 被处理之前会被处理。

while (running) {
  var message = getNextMessage();  // (1)
  dispatchMessage(message);  // (2)
  processMicroTaskQueue(); // (3)
}

因此,如果您有只执行阶段 (3) 的承诺,浏览器会一直停在 (3),因此不会有机会处理任何 macrotasks,即浏览器会挂起!!

希望这有意义,而且我已经使用了正确的术语等。

PS:与 3.11 非常相似,一个糟糕编写的应用程序从不给操作系统处理其事件循环的机会,实际上会导致整个操作系统挂起。奇怪的是,这些事情又回来了... what's the point of wrapping promise into setTimer() and not?

英文:

A slight miss conception of promises, is that there async. But there really only just a contract, that is then placed into a queue that will get processed before the next event loop. Very useful for writing async code, much nicer than callbacks.

Below is a simple example with 2 promises, 1 promise is not doing anything async, the other is doing a simple async sleep. That async sleep is very important, because this allows the browser to process the next event loop. If you take this sleep out, and re-run, watch how the browser will hang.

> Please NOTE: be prepared to use say Chrome's task manager to kill the
> browser TAB when you comment out the await sleep(1).

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

const sleep = ms =&gt; new Promise(resolve =&gt; setTimeout(resolve, ms));

async function nothingProm() {
  // a promise that does no async stuff
}

//this infinate loop will not hang the browser
async function test() {
  while (true) {
    await nothingProm();
    await sleep(1);  //remove this for HANG!!!     
  }
}

test();

<!-- end snippet -->

Now in the above it might seem strange why does removing that sleep cause the browser to hang.

Browsers use something called an event loop, this is responsible for getting things like mouse clicks, timers etc, and dispatching them to listeners. This is very similar to how cooperative multi-tasking OS's work, think Window 3.11.

So, inside the browser TAB there will be an Event Loop running, doing something like ->

while (running) {
  var message = getNextMessage();
  dispatchMessage(message);
}

That getNextMessage above will efficiently wait for some event, timer, mouse move, etc etc. So it won't be wasting CPU resources, even thought it's in this tight LOOP.

So what does this have to do with promises you may ask. Well this bit is where the microtask comes in, unlike macrotask like a timer, that the browser can dispatch from, there basically stuck into a queue that get drained before the next macrotask is processed.

while (running) {
  var message = getNextMessage();  // (1)
  dispatchMessage(message);  // (2)
  processMicroTaskQueue(); // (3)
}

So if you had promises that's only did stage (3), constantly the browser gets stuck at (3), as such does not get any chance to process any macrotasks, IOW: The browser HANGS!!

Hopefully that makes sense, and I've used the correct terminology etc.

ps. Very similar to 3.11, a badly written app that never gave chance for the OS to process it's event loop, would in fact hang the whole OS. Strange how these things come round again.. what's the point of wrapping promise into setTimer() and not?

答案3

得分: 0

通过在代码中添加计时器,您进一步确认承诺内部的代码是异步运行的。这只是为了模仿现实生活中异步操作(如获取数据)的行为。它等待2秒,然后执行您的操作,并在之后解析。

英文:

By adding a timer to your code, you are further confirming that the code inside the promise is running asynchronously. This is just to mimic the behavior of real-life examples for asynchronous operations like fetching data.
It waits for 2 seconds then perform your operations and resolve afterwards.

答案4

得分: -2

Promise.resolve 调度一个微任务,而 setTimeout 调度一个宏任务。而微任务会在下一个宏任务执行之前被执行。

英文:

Promise.resolve schedules a microtask and the setTimeout schedules a macrotask. And the microtasks are executed before running the next macrotask.

huangapple
  • 本文由 发表于 2023年5月17日 18:22:30
  • 转载请务必保留本文链接:https://go.coder-hub.com/76271061.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定