2017-07-17 42 views
1

我試圖解決以下挑戰,我必須編寫傳遞一個回調到processAction功能triggerActions,併產生輸出:JavaScript編碼挑戰與的setTimeout /異步輸出

"Process Action 1" 
"Process Action 2" 
... 
"Process Action n" 

這裏是提供功能:

function processAction(i, callback) { 
    setTimeout(function() { 
    callback("Processed Action " + i); 
    }, Math.random()*1000); 
} 

功能操作的代碼:

function triggerActions(count) { 

} 

請注意,processAction的代碼不能更改。我正在考慮使用Promise,但我不確定如何。我相信setTimeout實際上是同步的,所以我不知道async/await是否可以工作。

我嘗試:

triggerActions = count => { 
    let promises = []; 
    for(let i=1; i<=count; i++) { 
    promises.push(new Promise((resolve, reject) => processAction(i, str => resolve(str)))); 
    } 
    let results = [] 
    promises.forEach(promise => Promise.resolve(promise).then(async res => results.push(await res))); 
    return results; 
} 
+2

setTimeout的其實是** A **同步 - 你試過** **的任何代碼,RO你想有人來解決總的挑戰嗎? –

+0

[promisify](https://stackoverflow.com/q/22519784/1048572)'processAction',然後'async' /'await'將工作。 – Bergi

+0

@JaromandaX我剛剛用我的代碼編輯了我的帖子。 – fafafariba

回答

1

我挺喜歡簡短而親切:

var n = 5 
var stop = 1 

triggerActions = function(text) { 
    if (text) console.log(text) 
    if (stop <= n){ 
     processAction(stop++, triggerActions) 
    } 
} 
triggerActions() 

PS

它發生,我認爲也許你允許提供一個函數,意味着stop函數外的變量聲明是一個概率LEM。這使得它有點冗長,但你可以用它所有這樣的函數內部:

function triggerActions(stop) { 
    var rFn = (text) => { 
     if (text) console.log(text) 
     if (stop <= n){ 
      processAction(stop++, rFn) 
     } 
    } 
    rFn() 
} 
triggerActions(1) 
1

你去那裏:

// Your unaltered function 
 
function processAction(i, callback) { 
 
    setTimeout(function() { 
 
    callback("Processed Action " + i); 
 
    }, Math.random()*1000); 
 
} 
 

 
// The function you want to implement 
 
function triggerActions(count) { 
 
    var triggerAction = function (i) { // Local function to process the given action number: 
 
    if (i <= count) {     // More actions to execute? 
 
     processAction(i, function (text) {// Process current action number and pass a callback in parameter 
 
     console.log(text);    // Write the result of processAction    
 
     triggerAction(i + 1);   // Trigger the next action 
 
     });        // 
 
    }         // 
 
    }          
 
    triggerAction(1);      // First things first: start at action one 
 
} 
 

 
// Call the function 
 
triggerActions(10);

+0

我建議將條件放在'i ++'的前面,而不是在回調中,這樣當'count'爲零時代碼不會失敗。 – Bergi

+0

@Bergi謝謝你是對的。我更新了代碼,並且通過使用基於1的索引進行清除。 –

0

樓主的本能使用承諾是正確的。上述

兩個解決方案可以工作,但因爲每次調用triggerActions()必須等待延遲等待的下一個電話可以製成之前,這是相當緩慢的。

也許這是你想要的,但這裏的使用的承諾和Promise.all()的優化解決方案:

const processAction = (i, callback) => { 
    setTimeout(function() { 
    callback("Processed Action " + i); 
    }, Math.random()*1000); 
} 

const triggerActions = (n) => { 
    const promises = []; 
    const generatePromise = (i) => { 
    return new Promise((resolve, reject) => { 
     processAction(i, resolve); 
    }); 
    } 
    for (let i = 1; i <= n; i += 1) { 
    promises.push(generatePromise(i)); 
    } 
    Promise.all(promises) 
    .then((strings) => strings.forEach((string) => console.log(string))); 
} 

triggerActions(10); 

爲了比較的性能差異,試圖通過端運行這兩種方法的一面。