document.body.style = 'background:red';
document.body.style = 'background:yellow';
document.body.style = 'background:blue';
document.body.style = 'background:red';
setTimeout(function(){
document.body.style = 'background:yellow'
},0)
function loop() {
Promise.resolve().then(loop);
}
loop();
微任务会先于渲染执行
document.body.style = 'background:red';
console.log(1);
Promise.resolve().then(() => {
console.log(2);
document.body.style = 'background:yellow'
});
console.log(3);
宏任务结束之后会先执行微任务
setTimeout(() => {
console.log(1);
Promise.resolve(3).then(data => console.log(data))
}, 0)
setTimeout(() => {
console.log(2)
}, 0)
button.addEventListener('click', () => {
Promise.resolve().then(() => console.log('Micro task 1'));
console.log('Listener 1');//此时堆栈清空
});
button.addEventListener('click', () => {
Promise.resolve().then(() => console.log('Micro task 2'));
console.log('Listener 2');
});
// Listener1 Micro task 1 Listener 2 Micro task 2
//button.click();堆栈在执行完Listener1后没有清空。还在Script中
<body>
<a id="link" href="http://www.baidu.com">link</a>
<script>
let link = document.getElementById('link');
const nextTick = new Promise(resolve => {
link.addEventListener('click', resolve, { once: true });
});
nextTick.then(event => {
event.preventDefault();
console.log('event.preventDefault()');
});
//link.click();
</script>
</body>
<body>
<div id="tree"></div>
<button onclick="start()">开始监听</button>
<button onclick="changeAttribute()">修改属性</button>
<button onclick="addChild()">添加子节点,3秒后删除</button>
<script>
var targetNode = document.getElementById('tree');
var config = { attributes: true, childList: true, subtree: true };
var callback = function (mutationsList) {
for (var mutation of mutationsList) {
if (mutation.type == 'childList') {
console.log('一个子节点被添加或者删除了');
}
else if (mutation.type == 'attributes') {
console.log('属性 ' + mutation.attributeName + ' 被改变了.');
}
}
};
var observer = new MutationObserver(callback);
function start() {
observer.observe(targetNode, config);
}
function changeAttribute() {
targetNode.setAttribute('data-name', '树');
}
function addChild() {
let child = document.createElement('div');
child.innerHTML = '子节点';
targetNode.appendChild(child);
setTimeout(() => {
targetNode.removeChild(child);
}, 2000);
}
</script>
</body>
Ajax JS引擎线程=>异步http请求线程=>事件触发线程=>事件队列
let ret1 = 1 + 1;
let ret2 = 2 + 2;
let ret3 = 3 + 3;
let ret4 = 4 + 4;
console.log(ret1, ret2, ret3, ret4);
cnpm i readline-sync -S
let readline = require('readline-sync');
while (true) {
var num1 = readline.question('input num1: ');
var num2 = readline.question('input num2: ');
let ret = eval(num1 + "+" + num2);
console.log(ret);
}
const { fork } = require('child_process');
let tasks = [];
function showName() {
console.log("zhufeng")
}
function setTimeout(callback, timeout) {
let child = fork('./setTimeout.js');
child.on('message', function (message) {
if (message.ready) {
tasks.push(callback);
}
});
child.send({ type: 'timer', timeout });
}
setTimeout(showName, 1000);
setInterval(() => {
let task = tasks.shift();
task && task();
}, 100);
process.on('message', function (message) {
let { type, timeout } = message;
if (type === 'timer') {
let end = Date.now() + parseFloat(timeout);
setInterval(() => {
if (Date.now() >= end) {
process.send({ ready: true });
process.exit();
}
}, 100);
}
});
main.js
let tasks = [];
let delayTasks = [];
function showName() {
console.log("zhufeng");
}
function setTimeout(callback, timeout) {
delayTasks.push({ callback, start: Date.now(), timeout });
}
setTimeout(showName, 1000);
setInterval(() => {
let task = tasks.shift();
task && task();
delayTasks = delayTasks.filter((item) => {
if (item.start + item.timeout <= Date.now()) {
tasks.push(item.callback.bind(item));
return false;
}
return true;
});
}, 100);
<script>
function task() {
console.log('zhufeng');
}
function exec() {
setTimeout(task, 0);
let start = Date.now();
let end = start + 500;
while (Date.now() < end) {
console.log(1);
}
}
exec();
</script>
<script>
function task() { setTimeout(task, 0); }
setTimeout(task, 0);
</script>
const { fork } = require('child_process');
let tasks = [];
class XMLHttpRequest {
constructor() {
this.options = {};
}
open(method, url) {
this.options.method = method;
this.options.url = url;
}
send() {
let child = fork('./XMLHttpRequest.js');
child.on('message', (message) => {
if (message.type === 'response') {
this.response = message.data;
tasks.push(this.onload);
}
});
child.send({ type: 'send', options: this.options });
}
}
function getData() {
let xhr = new XMLHttpRequest();
xhr.open('GET', 'http://localhost:3000/data');
xhr.onload = function () {
console.log(xhr.response);
}
xhr.send();
}
getData();
setInterval(() => {
let task = tasks.shift();
task && task();
}, 100);
let url = require('url');
let http = require('http');
process.on('message', function (message) {
let { type, options } = message;
if (type == 'send') {
let urlObj = url.parse(options.url);
const config = {
hostname: urlObj.hostname,
port: urlObj.port,
path: urlObj.path,
method: options.method
};
var req = http.request(config, (res) => {
let chunks = [];
res.on('data', (chunk) => {
chunks.push(chunk);
});
res.on('end', () => {
process.send({
type: 'response',
data: JSON.parse(Buffer.concat(chunks).toString())
});
process.exit();
});
});
req.on('error', (err) => {
console.error(err);
});
req.end();
}
});
var http = require("http");
var server = http.createServer();
server.on("request", function (request, response) {
response.end(JSON.stringify({ message: 'hello' }));
})
server.listen(3000, function () {
console.log("服务器开启成功")
});
const { fork } = require('child_process');
let tasks = [];
let microTasks = []
class XMLHttpRequest {
constructor() {
this.options = {};
}
open(method, url) {
this.options.method = method;
this.options.url = url;
}
send() {
let child = fork('./XMLHttpRequest.js');
child.on('message', (message) => {
if (message.type === 'response') {
this.response = message.data;
tasks.push(this.onload);
}
});
child.send({ type: 'send', options: this.options });
}
}
function getData() {
let xhr = new XMLHttpRequest();
xhr.open('GET', 'http://localhost:3000/data');
xhr.onload = function () {
console.log(xhr.response);
}
xhr.send();
}
getData();
class Promise {
constructor(executor) {
executor(this.resolve);
}
then = (onResolve) => {
this._onResolve = onResolve;
}
resolve = (value) => {
microTasks.push(() => this._onResolve(value));
}
}
new Promise(function (resolve) {
resolve('promise1');
}).then(result => console.log(result));
new Promise(function (resolve) {
resolve('promise2');
}).then(result => console.log(result));
console.log('同步任务');
setInterval(() => {
let task = tasks.shift();
task && task();
microTasks.forEach(task => task());
microTasks = [];
}, 100);
requestAnimationFrame
回调函数运行在处理CSS之前的绘制之前getComputedStyle
可以迫使浏览器更早的执行样式计算 button.addEventListener('click', () => {
box.style.display = 'none';
box.style.display = 'block';
box.style.display = 'none';
box.style.display = 'block';
box.style.display = 'none';
window.getComputedStyle(box).marginLeft;
box.style.display = 'block';
box.style.display = 'none';
box.style.display = 'block';
box.style.display = 'none';
box.style.display = 'block';
});
<body>
<div style="background: lightblue;width: 0;height: 20px;"></div>
<button>走你</button>
<script>
/**
* requestAnimationFrame(callback) 由浏览器专门为动画提供的API
* cancelAnimationFrame(返回值) 清除动画
* <16.7 丢帧
* >16.7 跳跃 卡顿
*/
const div = document.querySelector('div');
const button = document.querySelector('button');
let start;
function progress() {
div.style.width = div.offsetWidth + 1 + 'px';
div.innerHTML = (div.offsetWidth) + '%';
if (div.offsetWidth < 100)
timer = requestAnimationFrame(progress);
else
console.log(Date.now() - start);
}
button.onclick = () => {
div.style.width = 0;
start = Date.now();
requestAnimationFrame(progress);
}
</script>
</body>
var handle = window.requestIdleCallback(callback[, options])
<body>
<script>
let task = () => {
console.log('requestAnimationFrame');
};
requestIdleCallback(idleWork, { timeout: 2000 });
// 任务队列
const tasks = [
() => {
console.log("第一个任务");
requestAnimationFrame(task);
},
() => {
console.log("第二个任务");
requestAnimationFrame(task);
},
() => {
console.log("第三个任务");
requestAnimationFrame(task);
},
];
function idleWork(deadline) {
console.log('deadline.timeRemaining()', deadline.timeRemaining());
while ((deadline.timeRemaining() > 0 || deadline.didTimeout) && tasks.length > 0) {
work();
}
if (tasks.length > 0)
requestIdleCallback(idleWork);
}
function work() {
tasks.shift()();
console.log('执行任务');
}
</script>
</body>
setTimeout(function () {
console.log('timeout');
},0);
setImmediate(function () {
console.log('immediate');
});
const fs = require('fs')
fs.readFile(__filename, () => {
setTimeout(() => {
console.log('timeout');
}, 0)
setImmediate(() => {
console.log('immediate')
})
})
setTimeout(() => {
console.log('setTimeout1')
Promise.resolve().then(function () {
console.log('promise1')
})
}, 0)
setTimeout(() => {
console.log('setTimeout2')
Promise.resolve().then(function () {
console.log('promise2')
})
}, 0)
setImmediate(() => {
console.log('setImmediate1')
Promise.resolve().then(function () {
console.log('promise3')
})
}, 0)
process.nextTick(() => {
console.log('nextTick1');
Promise.resolve().then(() => console.log('promise4'));
process.nextTick(() => {
console.log('nextTick2');
Promise.resolve().then(() => console.log('promise5'));
process.nextTick(() => {
console.log('nextTick3')
process.nextTick(() => {
console.log('nextTick4')
})
})
})
})
// nextTick1 nextTick2 nextTick3 nextTick4
//promise4 promise5 setTimeout1 promise1 setTimeout2 promise2 setImmediate1 promise3
let fs = require('fs');
setTimeout(() => {
console.log('1');
let rs1 = fs.createReadStream('./1.txt');
rs1.on('close', (data) => console.log('end_a'));
rs1.on('data', () => {
rs1.destroy();
setImmediate(() => console.log('setImmediate_a'));
setTimeout(() => {
console.log('setTimeout_a')
});
console.log('a');
});
console.log('2');
setImmediate(function () {
console.log('setImmediate1');
process.nextTick(() => console.log('nextTick1'));
});
setImmediate(function () {
console.log('setImmediate2');
process.nextTick(() => console.log('nextTick2'));
});
console.log('3');
setTimeout(() => {
console.log('setTimeout1');
process.nextTick(() => {
console.log('nextTick3')
process.nextTick(() => console.log('nextTick4'));
});
});
setTimeout(() => {
console.log('setTimeout2');
});
console.log('4');
}, 1000);
Promise.resolve().then(()=>{
console.log('Promise1')
setTimeout(()=>{
console.log('setTimeout2')
},0)
})
setTimeout(()=>{
console.log('setTimeout1')
Promise.resolve().then(()=>{
console.log('Promise2')
})
},0)
console.log('script start');
setTimeout(function() {
console.log('setTimeout');
}, 0);
Promise.resolve().then(function() {
console.log('promise1');
}).then(function() {
console.log('promise2');
});
console.log('script end');
async function async1() {
console.log('async1 start')
await async2()
console.log('async1 end')
}
async function async2() {
console.log('async2')
}
console.log('script start')
setTimeout(function () {
console.log('setTimeout')
})
async1()
new Promise(function (resolve) {
console.log('promise1')
resolve()
}).then(function () {
console.log('promise2')
})
console.log('script end')
script start
async1 start
async2
promise1
script end
async1 end
promise2
setTimeout
console.log(1);
setTimeout(() => {
console.log(2);
}, 10);
new Promise(function (resolve) {
console.log(3);
resolve();
console.log(4);
}).then(function () {
console.log(5);
});
console.log(6);
requestIdleCallback(() => console.log(7));
requestAnimationFrame(() => console.log(8));
const Promise = require('./Promise')
Promise.resolve().then(() => {
console.log(1);
return Promise.resolve(Promise.resolve('hello'))
}).then((res) => {
console.log(res)
})
Promise.resolve().then(() => {
console.log(2);
}).then(() => {
console.log(3);
}).then(() => {
console.log(4);
}).then(() => {
console.log(5);
}).then(() => {
console.log(6);
})