Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/468.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 为什么Promise对象会阻止渲染?_Javascript_Promise_Settimeout_Es6 Promise - Fatal编程技术网

Javascript 为什么Promise对象会阻止渲染?

Javascript 为什么Promise对象会阻止渲染?,javascript,promise,settimeout,es6-promise,Javascript,Promise,Settimeout,Es6 Promise,我正在测试Promise对象,并编写了一些代码来模拟长时间运行的同步任务。我在比较Promise和setTimeout-参见: 承诺vs设置超时 使用慢速运行功能设置超时 承诺和慢速运行功能 明确的结果 结果 常数慢=函数(){ 设nu=Date.now(); 而(Date.now()-nu新承诺(解析=>{ 慢(); 解决(); }); const resultsElement=document.getElementById('result') 常量日志=(消息)=>{ resultElem

我正在测试Promise对象,并编写了一些代码来模拟长时间运行的同步任务。我在比较Promise和setTimeout-参见:


承诺vs设置超时
使用慢速运行功能设置超时
承诺和慢速运行功能
明确的结果
结果
常数慢=函数(){
设nu=Date.now();
而(Date.now()-nu<1000){}
}
const getSlowPromise=()=>新承诺(解析=>{
慢();
解决();
});
const resultsElement=document.getElementById('result')
常量日志=(消息)=>{
resultElement.innerText+=消息;
}  
const setTimeExputton=document.getElementById('settimeout-test');
SetTimeExputton.addEventListener('单击',()=>{
const now=Date.now();
日志(`\nsetTimeout测试在${Date.now()-now}ms`之后开始);
设置超时(()=>{
慢();
log(`\n low函数在${Date.now()-now}ms`之后完成);
}, 0);
日志(`\nEvent listener在${Date.now()-now}ms`之后完成);
});
const promiseButton=document.getElementById('promise-test');
promiseButton.addEventListener('单击',()=>{
const now=Date.now();
日志(`\nsetTimeout测试在${Date.now()-now}ms`之后开始);
getSlowPromise().then(res=>log(`\n promise在${Date.now()-now}ms`)之后完成);
日志(`\nevent listener在${Date.now()-now}ms`之后完成);
})
const clear=()=>resultElement.innerText='';
const clearButton=document.getElementById('clear');
addEventListener('click',()=>clear());
我认为Promise和setTimeout的行为类似,将代码添加到任务队列中,然后继续执行。结果的顺序是相同的,但长时间运行的任务的承诺似乎会阻止渲染,直到长时间运行的任务完成。有人能解释一下吗

该示例在Chrome中运行得最好

更新: 我并不是想让长时间运行的任务并行运行,我只是想了解为什么Promise和setTimeout在我的示例中表现不同。但是,如果您确实希望并行运行任务,那么Web工作者/工作者线程就是昆汀建议的方法

但我的问题的答案似乎是,正如Bergi在评论中所写,Promise构造函数是同步的。 这里有一个较长的
,而(Date.now()-nu<1000){}
模拟同步的长时间运行的任务。它是一个同步的长时间运行的任务

承诺是一种管理异步代码的方法,而不是使代码异步的方法,也不是模拟多线程的方法

为此,你需要看看工人

  • 对于浏览器
  • 对于Node.js

因为
while(Date.now()-nu<1000){}
阻止渲染-承诺不会魔术般地消除同步紧循环,例如
setTimeout
排队调用也会在事件循环的不同部分运行,而不像
Promise.then
调用这样的微任务。虽然这不是示例代码的问题,但如果您希望它们在所有情况下都是等效的,那么它会给您带来问题。。您正在寻找
Promise.resolve()。然后(慢速)
类似于
setTimeout(慢速,0)
Thank You@Bergi这就是我想要的答案。如果你把它作为一个答案,我会接受的。你是对的,这是一个长期运行的任务,我只是说它模拟了一个更有意义的任务。我认为该代码是异步的,因为在这两种情况下,它实际上都是在Promise或setTimeout中运行代码之前运行对log函数的最后一次调用。但它当然不会并行运行,因为javascript是单线程的。但我并不是想并行运行,我只是想理解为什么Promise和setTimeout的行为不同。
<!DOCTYPE html>
<html>

  <head>
    <link rel="stylesheet" href="style.css">
  </head>

  <body>
    <h2>Promise vs setTimeout</h2>
    <div><button id="settimeout-test">setTimeout with slow running function</button></div>
    <div><button id="promise-test">Promise and slow running function</button></div>
    <div><button id="clear">Clear Results</button></div>
    <h5>Results</h5>
    <div id="result"></div>

    <script>
        const slow = function() {
            let nu = Date.now();
            while (Date.now() - nu < 1000) {}
        }
        const getSlowPromise = () => new Promise(resolve => {
                slow();
                resolve();
        });
        const resultsElement = document.getElementById('result')
        const log = (message) => {
            resultsElement.innerText += message;
        }  

        const settimeoutButton = document.getElementById('settimeout-test');
        settimeoutButton.addEventListener('click', () => {
            const now = Date.now();
            log(`\nsetTimeout test starts after ${Date.now() - now} ms`);
            setTimeout(() => {
                slow();
                log(`\nSlow function completes after ${Date.now() - now} ms`);
            }, 0);
            log(`\nEvent listener completes after ${Date.now() - now} ms`);
        });

        const promiseButton = document.getElementById('promise-test');
        promiseButton.addEventListener('click', () => {
            const now = Date.now();
            log(`\nsetTimeout test starts after ${Date.now() - now} ms`);
            getSlowPromise().then(res => log(`\nPromise completes after ${Date.now() - now} ms`));
            log(`\nevent listener completes after ${Date.now() - now} ms`);
        })

        const clear = () => resultsElement.innerText = '';
        const clearButton = document.getElementById('clear');
        clearButton.addEventListener('click', () => clear());

    </script>

  </body>

</html>