2016-04-15 33 views
2

我試圖從異步任務中返回承諾,以便我可以使用。然後()調用使它們同步。不幸的是,我正在經歷一些真正奇怪的行爲。基本上,第二個then()在第二個解決之前執行。有人可以解釋發生了什麼嗎?這裏是我的代碼:爲什麼.then()在promise實際解決之前觸發?

function runReleaseLoop() { 
    console.log('Starting release loop'); 
    const themes = ['blue', 'red']; 
    return new Promise(resolve => { 
    buildReleases(themes, resolve); 
    }) 
} 

function buildReleases(themes, onComplete) { 
    console.log(themes); 
    if (themes.length === 0) { 
    onComplete(); 
    } else { 
    const theme = themes.pop(); 
    Promise.resolve() 
     .then(setTheme(theme)) 
     .then(someDelayedTask(theme)) 
     .then(buildReleases(themes, onComplete)); 
    } 
} 

function setTheme(theme) { 
    return new Promise(resolve => { 
    console.log(`Setting theme to ${theme}`); 
    resolve(); 
    }); 
} 

function someDelayedTask(theme) { 
    console.log(`Starting delayed task related to ${theme}`); 
    return new Promise(resolve => { 
    setTimeout(() => { 
     console.log(`Finished delayed task related to ${theme}`); 
     resolve(); 
    }, 3000) 
    }); 
} 

// Run the process 
runReleaseLoop() 
    .then(() => { 
    console.log('Release loop finished') 
    }); 

這裏是我的控制檯輸出:

"Starting release loop" 
["blue", "red"] 
"Setting theme to red" 
"Starting delayed task related to red" 
["blue"] 
"Setting theme to blue" 
"Starting delayed task related to blue" 
[] 
"Release loop finished" 
"Finished delayed task related to red" 
"Finished delayed task related to blue" 
+0

因此,對於帶參數的,我需要返回,返回一個承諾函數的功能是什麼? – ordanj

+0

是的正確(哎呀刪除第一個評論大聲笑),但你也需要採取行動的承諾,返回,等 – Deryck

回答

1

你調用這些功能的同步(setThemesomeDelayedTask,並buildReleases),然後通過他們的返回值(許諾)成then而不是傳遞函數本身進入然後:

Promise.resolve() 
    .then(setTheme(theme)) 
    .then(someDelayedTask(theme)) 
    .then(buildReleases(themes, onComplete)); 

這裏是一個解決方案:

Promise.resolve() 
    .then(_ => setTheme(theme)) 
    .then(_ => someDelayedTask(theme)) 
    .then(_ => buildReleases(themes, onComplete)); 

這裏是你的代碼的輸出與上述變化:

Starting release loop 
[ 'blue', 'red' ] 
Setting theme to red 
Starting delayed task related to red 
Finished delayed task related to red 
[ 'blue' ] 
Setting theme to blue 
Starting delayed task related to blue 
Finished delayed task related to blue 
[] 
Release loop finished 
+0

你也可以做這樣的事情: Promise.resolve() .then(setTheme) .then(someDelayedTask) .then(buildReleases); – northsideknight

0

的第一個問題是,你混有回調的承諾。第二個是你調用所有功能setTheme, someDelayedTask, buildReleases在一個時間:

function runReleaseLoop() { 
    console.log('Starting release loop'); 
    const themes = ['blue', 'red']; 
    return buildReleases(themes); 
} 

function buildReleases(themes) { 
    console.log(themes); 
    if (themes.length === 0) { 
    return Promise.resolve(); 
    } 

    const theme = themes.pop(); 
    return setTheme(theme) 
    .then(() => someDelayedTask(theme)) 
    .then(() => buildReleases(themes)); 
} 

function setTheme(theme) { 
    console.log(`Setting theme to ${theme}`); 
} 

function someDelayedTask(theme) { 
    console.log(`Starting delayed task related to ${theme}`); 
    return new Promise(resolve => { 
    setTimeout(() => { 
     console.log(`Finished delayed task related to ${theme}`); 
     resolve(); 
    }, 3000) 
    }); 
} 

// Run the process 
runReleaseLoop() 
    .then(() => console.log('Release loop finished')); 
相關問題