2016-09-29 26 views
0

我想了解ES6承諾(和承諾一般),但事情並不清楚。我試圖讓這段代碼運行:我的ECMA 6承諾不同步解決

var function1 = function() { 
    console.log("function 1 has started") 
} 

var function2 = new Promise((resolve, reject) => { 
    console.log("function2 has started"); 
    setTimeout(function() { 
     console.log("function2 has ended") 
     resolve(); 
    }, 3000) 
}) 

var function3 = new Promise((resolve, reject) => { 
    console.log("function3 has started"); 
    setTimeout(function() { 
     console.log("function 3 has ended") 
     resolve() 
    },2000) 
}) 

var myFunc = function() { 
    function3.then(function2).then(function1()) 
} 

myFunc(); 

輸出我的預期:

function3 has started 
//after 2 seconds 
function3 has ended 
function2 has started 
//after 3 seconds 
function2 has ended 
function1 has started 

輸出我得到:

function2 has started 
function3 has started 
function1 has started 
//after 2 seconds 
function3 has ended 
//1 second more 
function2 has ended 

你能解釋我我做錯了什麼在我的代碼?

回答

2

兩件事情要記住:

  • 當調用構造函數的承諾,傳遞的回調函數總是將立即被從構造函數的調用裏面。
  • 您傳遞給then()或catch()的回調從不會立即調用。

因此,在方案中,字符串「函數2已開始」和「功能3已經開始」打印因爲這兩個承諾都construcuted

此後立即打印「函數1已啓動」,因爲您直接從myFunc()中調用它。你可能意味着傳遞功能1 沒有括號這樣的:

function3.then(function2).then(function1) 

在這種情況下,功能1只會在最後調用(如你預期),一旦雙方承諾已經履行。

我認爲剩下的兩個輸出的順序是清楚的,當setTimeout回調被調用時,「已結束」消息被打印出來。

以下產生您期望的輸出。

var function1 = function() { 
    console.log("function 1 has started") 
} 

var function2 = function() { 
    return new Promise((resolve, reject) => { 
     console.log("function2 has started"); 
     setTimeout(function() { 
      console.log("function2 has ended") 
      resolve(); 
     }, 3000); 
    }); 
}; 

var function3 = function() { 
    return new Promise((resolve, reject) => { 
     console.log("function3 has started"); 
     setTimeout(function() { 
      console.log("function 3 has ended") 
      resolve() 
     }, 2000); 
    }); 
}; 

var myFunc = function() { 
    function3().then(function2).then(function1); 
} 

myFunc(); 
+0

謝謝您提供此信息。這很清楚。我應該如何重構我的代碼才能獲得我期望的輸出結果?這對我沒有意義:( – Pechou

+0

添加了一個可以產生預期輸出的代碼版本。第二個承諾現在只在第一個承諾滿足時才構建(導致定時器按順序運行) - 而在您的版本中,兩個Promise都是在開始時構建的(導致定時器並行運行)。 – Jens

+0

乾杯隊友!非常感謝,我明白了! – Pechou