Amu*_*ran 1 javascript jquery asynchronous
我创建了两个按钮。一个名为“同步”,另一个名为“异步”。当我单击“同步”按钮时,它应该使用循环处理大数组,并冻结浏览器,直到循环完成处理更大的数组。当我按下“异步”按钮时。它应该处理相同的大数组而不冻结浏览器。如何使用 setTimeOut 函数执行此操作?
在 ES7 中使用 async/await 这变得非常简单。花费太长时间的长循环示例
function main() {
const numOperations = 1000000000;
let sum = 0;
for (let i = 0; i < numOperations; ++i) {
sum += doSomeOperation(i);
}
console.log(sum);
}
main();
function doSomeOperation(v) {
return v * 1.1 / (v + 1);
}Run Code Online (Sandbox Code Playgroud)
使用 async/await 使其偶尔屈服于浏览器的示例
async function main() {
const numOperations = 1000000000;
const iterationsPerChunk = 10000000;
let sum = 0;
for (let i = 0; i < numOperations; ++i) {
if (i && i % iterationsPerChunk === 0) {
await oneMoment();
}
sum += doSomeOperation(i);
}
console.log(sum);
}
main();
function doSomeOperation(v) {
return v * 1.1 / (v + 1);
}
function oneMoment() {
return new Promise(resolve => setTimeout(resolve));
}Run Code Online (Sandbox Code Playgroud)
选择一个好的价值iterationsPerChunk可能会更困难。您可以轻松地创建一些类来检查performance.now并仅在经过一定时间(例如 1/2 秒或 1 秒)时调用 wait。每次调用setTimeout都会产生 5 毫秒到 20 毫秒的时间,因此您不想等待太频繁,但它确实使其易于使用。
示例使用performance.now
async function main() {
const numOperations = 1000000000;
let sum = 0;
let then = performance.now();
for (let i = 0; i < numOperations; ++i) {
// calling performance.now is slow
// so only check every 1000 iterations
if (i && i % 1000 === 0) {
const now = performance.now();
// have 0.1 second elapsed?
if (now - then > 100) {
await oneMoment();
then = performance.now();
}
}
sum += doSomeOperation(i);
}
console.log(sum);
}
main();
function doSomeOperation(v) {
return v * 1.1 / (v + 1);
}
function oneMoment() {
return new Promise(resolve => setTimeout(resolve));
}Run Code Online (Sandbox Code Playgroud)
更新:
我听说有传言,时间限制setTimeout可能会被取消,因为您可以通过通过向自己发布消息来解决这些限制postMessage。
您仍然遇到同样的问题,postMessage 确实需要一些时间,但通常是微秒或更短。
const pause = (function() {
let reqId = 0;
const reqs = new Map();
window.addEventListener('message', (e) => {
const resolve = reqs.get(e.data);
if (resolve) {
reqs.delete(e.data);
resolve();
}
});
return _ => new Promise(resolve => {
const id = reqId++;
reqs.set(id, resolve);
window.postMessage(id);
});
})();
async function main() {
const numOperations = 1000000000;
const iterationsPerChunk = 10000;
const startTime = performance.now();
let sum = 0;
for (let i = 0; i < numOperations; ++i) {
if (i && i % iterationsPerChunk === 0) {
await pause();
}
sum += doSomeOperation(i);
}
const elapsedTime = performance.now() - startTime;
console.log(sum);
console.log(`elapsedTime: ${(elapsedTime * 0.001).toFixed(2)}seconds`);
}
main();
function doSomeOperation(v) {
return v * 1.1 / (v + 1);
}
function oneMoment() {
return new Promise(resolve => setTimeout(resolve));
}Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4318 次 |
| 最近记录: |