标签: event-loop

有没有例子证明微任务是在渲染之前执行的?

我看到几篇文章说渲染步骤是在微任务之后。

我用这段代码测试它:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title></title>
</head>
<body>
  <p>test</p>
  <script>
const p = document.querySelector('p');
p.textContent = 'text';
Promise.resolve().then(function microtask() {
  debugger;
  p.textContent = 'Promise';
});
  </script>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)

这段代码似乎表明 UI在微任务运行之前重新渲染

难道是我想错了?有没有什么好的例子表明渲染是在微任务运行之后进行的?

javascript event-loop html-rendering

4
推荐指数
1
解决办法
1199
查看次数

JavaScript 事件循环乱序执行

我正在尝试书中的一个示例来确认 JavaScript 事件循环是如何工作的,下面是代码

const baz = () => console.log("baz");
const bar = () => console.log("bar");

const foo = () => {
    console.log("foo");
    setTimeout(bar, 0);
    baz();
}
foo();
Run Code Online (Sandbox Code Playgroud)

setTimeout 这里的工作原理很简单(无序执行)输出是

foo
baz
bar 
Run Code Online (Sandbox Code Playgroud)

我不明白的是我添加一行时的顺序

const baz = () => console.log("baz");
const bar = () => console.log("bar");

const foo = () => {
    console.log("foo");
    setTimeout(bar, 0);
    baz();
}
setTimeout(baz, 0); // this somehow runs before foo() is finished
foo();
Run Code Online (Sandbox Code Playgroud)

输出是

foo
baz
baz 
bar
Run Code Online (Sandbox Code Playgroud)

为什么第二个 setTimeout 在 foo() 完成之前就被冲洗掉了?

javascript event-loop settimeout

4
推荐指数
1
解决办法
776
查看次数

为什么 MV3 Chrome 扩展(使用 Service Workers)必须“在事件循环的第一轮注册监听器”?

因此,我正在将使用持久后台页面的 MV2 扩展迁移到 MV3。在 Chrome 迁移指南 [https://developer.chrome.com/docs/extensions/mv3/migration_to_service_workers/#event_listeners] 中,它说:

为了让 Chrome 成功地将事件分派给适当的侦听器,扩展程序必须在事件循环的第一轮注册侦听器。实现此目的最直接的方法是将事件注册移至 Service Worker 脚本的顶层。

当 Service Worker 终止时,与其关联的事件侦听器也会终止。由于事件是在 Service Worker 启动时分派的,因此异步注册事件会导致事件被丢弃,因为首次启动时没有注册侦听器。

我的问题:

  1. 为什么我们必须这样注册呢?如果我们在等待异步操作后注册会有什么问题?
  2. 如果确实当一个 Service Worker 被终止时,与其关联的事件监听器也被终止,那么如果事件监听器都被终止,那么为什么不活动的 Service Worker 会突然变得活动呢?(我假设如果事件侦听器终止,它不会侦听事件。)
// background.js(service worker)
chrome.storage.local.get(["badgeText"], ({ badgeText }) => {
  chrome.action.setBadgeText({ text: badgeText });

  // Listener is registered asynchronously
  // This is NOT guaranteed to work in Manifest V3/service workers! Dont do this
  chrome.action.onClicked.addListener(handleActionClick);
});
Run Code Online (Sandbox Code Playgroud)

javascript event-loop google-chrome-extension chrome-extension-manifest-v3 chrome-extension-manifest-v2

4
推荐指数
1
解决办法
1151
查看次数

有效的事件循环实现?

可能的重复:
您将如何实现基本的事件循环?

并不是一个特定于语言的问题。什么是事件循环的有效实现?到目前为止,我只遇到过这样的事情:

while (true) {
    handleEvents();
    sleep(100);
}
Run Code Online (Sandbox Code Playgroud)

我认为这不是最好的方法-如果睡眠时间太短,它将消耗大量CPU,如果睡眠时间太长,则该应用将无响应。

那么,有没有更好的方法?

谢谢

events event-loop

3
推荐指数
1
解决办法
960
查看次数

为什么asyncio.wait不等待FIRST_COMPLETED

我是Python 3.5 asyncio的新手.

在下面的代码中,asyncio.wait()不等待stop_future完成:

import asyncio
import datetime
from concurrent.futures import FIRST_COMPLETED


def stop():  # callback after 12 seconds

    print('stop', datetime.datetime.now())
    stop_future.set_result('Done!')


async def display_dt():

    while not stop_future.done():
        print('dt-1', datetime.datetime.now())
        # sleep 5 seconds or stop_future done
        asyncio.wait([await asyncio.sleep(5), stop_future],  return_when=FIRST_COMPLETED)
        print('dt-2', datetime.datetime.now())

    task = asyncio.Task.current_task()
    task.cancel()
    print(stop_future.result())


loop = asyncio.get_event_loop()
stop_future = asyncio.Future()
loop.call_later(12, stop)
loop.run_until_complete(display_dt())
loop.close() 
Run Code Online (Sandbox Code Playgroud)

结果:

dt-1 2015-11-08 00:49:37.324582
dt-2 2015-11-08 00:49:42.325503
dt-1 2015-11-08 00:49:42.325503
dt-2 2015-11-08 00:49:47.326423
dt-1 2015-11-08 00:49:47.326423
stop 2015-11-08 00:49:49.327192  # async.wait stop_future …
Run Code Online (Sandbox Code Playgroud)

python future event-loop python-asyncio python-3.5

3
推荐指数
1
解决办法
1795
查看次数

Python 中的两个独立异步循环

使用async/await?执行在 Python 中并行运行的两个异步循环的好方法是什么?

我也想过类似下面的代码,但不能换我围绕着如何使用头async/ await/EventLoop在这种特殊情况下。

import asyncio

my_list = []

def notify():
    length = len(my_list)
    print("List has changed!", length)

async def append_task():
    while True:
        time.sleep(1)
        await my_list.append(random.random())
        notify()

async def pop_task():
    while True:
        time.sleep(1.8)
        await my_list.pop()
        notify()

loop = asyncio.get_event_loop()
loop.create_task(append_task())
loop.create_task(pop_task())
loop.run_forever()
Run Code Online (Sandbox Code Playgroud)

预期输出:

$ python prog.py
List has changed! 1 # after 1sec
List has changed! 0 # after 1.8sec
List has changed! 1 # after 2sec
List has changed! 2 # …
Run Code Online (Sandbox Code Playgroud)

python asynchronous event-loop python-3.x python-asyncio

3
推荐指数
1
解决办法
1万
查看次数

js while(true){}阻止事件循环

 setInterval(function(){console.log("hello")},2000);
 while(true){}
Run Code Online (Sandbox Code Playgroud)

"你好"永远不会被打印出来.我认为事件循环在不同的线程中运行,但是在这里看起来像'while循环'阻止了'事件循环'的执行. 有人可以对此有所了解吗?

我对js非常天真,如果问题太基础,那就很抱歉.

javascript event-loop

3
推荐指数
2
解决办法
1194
查看次数

无法在 React PHP 中进行非阻塞 I/O

我试图在数据库中插入一条记录到反应套接字服务器。我不知道如何以非阻塞方式进行操作

$loop = Factory::create();

$server = new Server('127.0.0.1:4040', $loop);
$database = new Database();

$server->on('connection', function(ConnectionInterface $conn)  use ($database) {
    $conn->write('Welcome, you can start writing your notes now...');

    $conn->on('data', function($data) use ($conn, $database) {
        $database->write($data);
        $conn->write('I am supposed to execute before database write');
    });
});

$loop->run();
Run Code Online (Sandbox Code Playgroud)

write数据库中的方法在sleep(10)执行sql语句之前有几秒钟的时间。所以我期待I am supposed to..应该立即打印下一条消息。

我的期望是,当有 I/O 操作时,该操作将被移动到事件表并且不会阻塞调用堆栈。根据事件循环和非阻塞的定义。

如何以非阻塞方式执行相同的操作。

谢谢

php nonblocking event-loop reactphp

3
推荐指数
1
解决办法
850
查看次数

以下 queueMicrotask polyfill 如何回退到使用 setTimeout?

考虑以下polyfill for queueMicrotask.

if (typeof window.queueMicrotask !== "function") {
  window.queueMicrotask = function (callback) {
    Promise.resolve()
      .then(callback)
      .catch(e => setTimeout(() => { throw e; }));
  };
}
Run Code Online (Sandbox Code Playgroud)

MDN 上的描述说明。

它通过使用立即解决的承诺来创建微任务,如果无法创建承诺,则回退到使用超时。

队列microtask库也使用相同的填充工具。这是它的文档所说的。

  • 在所有现代环境中的最佳性能。
    • queueMicrotask在现代环境中使用(最佳)
    • 回退到Promise.resolve().then(fn)Node.js 10 及更早版本,以及旧浏览器(最佳)
    • setTimeout在没有 Promise 的 JS 环境中回退(慢)

这提出的问题多于答案。

  • 那岂不Promiseundefined在JS环境,而无需承诺?
  • 为什么我们抛出错误而不是调用callbackinside setTimeout
  • 为什么我们使用单独的catch而不是将错误处理程序传递给then
  • setTimeout当“无法创建承诺”时,这个 polyfill 如何回退到使用?
  • 什么时候不创建承诺?

我本来希望 polyfill 实现如下。

if (typeof window.queueMicrotask !== "function") {
  window.queueMicrotask = …
Run Code Online (Sandbox Code Playgroud)

javascript event-loop settimeout promise es6-promise

3
推荐指数
1
解决办法
1274
查看次数

像“点击”这样的事件是宏任务吗?

代码:

setTimeout(() => console.log(1), 10);
for (let i = 0; i < 3e9; i++) {}
console.log(0);
window.onclick = () => console.log('click');
Run Code Online (Sandbox Code Playgroud)

运行此脚本时:

所以我有两个问题:

  1. 如果“点击”是一个宏任务,那么它应该在 setTimeout 后进入宏任务回调队列吗?这样当同步代码完成时,堆栈为空,宏任务回调队列将console.log(0) 放入堆栈,堆栈执行它,然后回调队列将console.log('click') 放入堆栈并堆栈执行它。
  2. 如果我在第 2 行的同步代码运行时单击,为什么我会在控制台中看到“单击”?我在 executor 到达第 4 行之前点击了...

javascript event-loop

3
推荐指数
1
解决办法
55
查看次数