我看到几篇文章说渲染步骤是在微任务之后。
我用这段代码测试它:
<!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 事件循环是如何工作的,下面是代码
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() 完成之前就被冲洗掉了?
因此,我正在将使用持久后台页面的 MV2 扩展迁移到 MV3。在 Chrome 迁移指南 [https://developer.chrome.com/docs/extensions/mv3/migration_to_service_workers/#event_listeners] 中,它说:
为了让 Chrome 成功地将事件分派给适当的侦听器,扩展程序必须在事件循环的第一轮注册侦听器。实现此目的最直接的方法是将事件注册移至 Service Worker 脚本的顶层。
当 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
可能的重复:
您将如何实现基本的事件循环?
并不是一个特定于语言的问题。什么是事件循环的有效实现?到目前为止,我只遇到过这样的事情:
while (true) {
handleEvents();
sleep(100);
}
Run Code Online (Sandbox Code Playgroud)
我认为这不是最好的方法-如果睡眠时间太短,它将消耗大量CPU,如果睡眠时间太长,则该应用将无响应。
那么,有没有更好的方法?
谢谢
我是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) 使用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) setInterval(function(){console.log("hello")},2000);
while(true){}
Run Code Online (Sandbox Code Playgroud)
"你好"永远不会被打印出来.我认为事件循环在不同的线程中运行,但是在这里看起来像'while循环'阻止了'事件循环'的执行.
有人可以对此有所了解吗?
我对js非常天真,如果问题太基础,那就很抱歉.
我试图在数据库中插入一条记录到反应套接字服务器。我不知道如何以非阻塞方式进行操作
$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 操作时,该操作将被移动到事件表并且不会阻塞调用堆栈。根据事件循环和非阻塞的定义。
如何以非阻塞方式执行相同的操作。
谢谢
考虑以下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 环境中回退(慢)
这提出的问题多于答案。
Promise是undefined在JS环境,而无需承诺?callbackinside setTimeout?catch而不是将错误处理程序传递给then?setTimeout当“无法创建承诺”时,这个 polyfill 如何回退到使用?我本来希望 polyfill 实现如下。
if (typeof window.queueMicrotask !== "function") {
window.queueMicrotask = …Run Code Online (Sandbox Code Playgroud) 代码:
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)
运行此脚本时:
如果我在第 2 行上的同步代码运行时不“单击”控制台显示预期结果:
0
1
Run Code Online (Sandbox Code Playgroud)
如果我在第 2 行的同步代码运行时“单击”控制台会显示意外结果:
0
click
1
Run Code Online (Sandbox Code Playgroud)
所以我有两个问题:
event-loop ×10
javascript ×6
python ×2
settimeout ×2
asynchronous ×1
chrome-extension-manifest-v2 ×1
chrome-extension-manifest-v3 ×1
es6-promise ×1
events ×1
future ×1
nonblocking ×1
php ×1
promise ×1
python-3.5 ×1
python-3.x ×1
reactphp ×1