2017-05-26 42 views
2

我有以下代码:承诺为基础的功能回路不运行异步

function asyncLoop() { 
    return new Promise(function(res, rej) { 
     for(let i=0;i<=400000000;i++) { 
      if(i===400000000) {console.log("done"); res();} 
     } 
    }); 
} 

asyncLoop().then(()=>{console.log("then")}); 
console.log("out"); 

我得到以下输出:

done 
out 
then 

据我承诺的理解,asyncLoop应该异步运行及以下应该是输出:

out 
done 
then 

什么我错过了吗?

+0

https://stackoverflow.com/a/5436869/1278540然后VS做 –

+1

@DebajyotiDas这是关于jQuery的承诺 - 这使用本机。 – Jamiec

+0

Promise没有“魔术”属性来创建一些尚未异步的异步事件。它们只是一个标准化的通知和错误处理方案 - 仅此而已。如果底层操作不是异步的,那么将其包装在承诺中不会以某种方式使其变为异步。 – jfriend00

回答

3

您的循环位于您传递给new Promise的回调中。该功能被称为“执行人”:

function executor(resolve, reject) 

执行人由new Promise称为同步。执行者的角色是设置任何异步事件以便最终调用resolvereject

见MDN:Promise constructor parameters

此功能与解析功能作为它的两个参数立即调用。

构造函数不会返回,直到执行完成

2

你做出了错误的假设。 Promise并不意味着是异步的,它们被用在异步的上下文中,以更简单的方式来处理这些调用。要使某种过程“异步”,您可以使用setTimeout()

function asyncLoop() { 
    return new Promise(function(res, rej) { 
     setTimeout(function() { 
      for(let i=0;i<=400000000;i++) { 
       if(i===400000000) {console.log("done"); res();} 
      } 
     }, 0); 
    }); 
} 

asyncLoop().then(()=>{console.log("then")}); 
console.log("out"); 
+1

JavaScript是单线程的,这会阻止主浏览器线程,与原始问题一样多,只能在事件循环的下一次运行中使用。 – jib

+0

事实上@jib,你是对的。这不是真的异步,只是延迟。 – Booster2ooo

1

允诺仅仅是一个返回值一个附加的回调而不是传递的回调函数,有几个好处的约定。有关更多信息,请参阅MDN上的Using promises

JavaScript是单线程的事件循环。 .thensetTimeout时间表事件。

所有的JavaScript运行在浏览器的主线程,除非创建worker

function asyncLoop() { 
 
    for (let i = 0; i <= 400000000; i++) { 
 
    if (i == 400000000) { 
 
     self.postMessage('done'); 
 
    } 
 
    } 
 
} 
 

 
var blob = new Blob(["onmessage = " + asyncLoop.toString()], 
 
        {type: "text/javascript"}); 
 

 
var worker = new Worker(window.URL.createObjectURL(blob)); 
 

 
worker.onmessage = e => console.log(e.data); 
 
worker.postMessage("start");

+0

感谢您在Web Workers上的分享!现在探索。 – delfuego17