2017-12-02 29 views
3

私は出力を期待していました:A、B、Cしかし、それは動作しません。関数handleClick(element)を変更できない場合、どのようにしてすべてのコードが順番に実行され、A、B、Cが期待どおりに出力されるように他の関数を変更できますか?JavaScriptを順番に実行する方法は?

async function handleClick(element) { 
 
    setTimeout(function(){ 
 
    console.log(`Click on Element_${element}`); 
 
    } 
 
    , Math.random(5)*1000); 
 
} 
 

 
async function clickLetter(letter) { 
 
    await handleClick(letter); 
 
} 
 

 
async function clickGroup(group) { 
 
    await handleClick(group); 
 
} 
 

 
const letters = ['A', 'B', 'C']; 
 

 
function clickLetters(letters, fn) { 
 
    let index = 0; 
 
    return new Promise(function(resolve, reject) { 
 
    function next() { 
 
     if (index < letters.length) { 
 
     fn(letters[index++]).then(next, reject); 
 
     } else { 
 
     resolve(); 
 
     } 
 
    } 
 
    next(); 
 
    }); 
 
} 
 

 
clickLetters(letters, clickLetter);

+0

あなたは、あなたの答えを得た 'async'ライブラリ、https://caolan.github.io/async/docs.html#eachSeries – Cristy

+0

を使用することができますか? –

+0

@Cristyいいえ、できません。約束は役に立たない。 – Bergi

答えて

1

setTimeout関数は非同期であり、結果がすぐに返され、あなたが約束コンストラクタ内でこれをラップし、それを解決する必要があります。

function handleClick(element) { 
 
    return new Promise((resolve, reject) => { 
 
    setTimeout(() => { 
 
     console.log(`Clicked on Element_${element}`); 
 
     resolve(); 
 
    }, Math.random(5) * 1000); 
 
    }); 
 
} 
 

 
async function clickLetter(letter) { 
 
    await handleClick(letter); 
 
} 
 

 
async function clickGroup(group) { 
 
    await handleClick(group); 
 
} 
 

 
const letters = ['A', 'B', 'C']; 
 

 
async function clickLetters(letters, fn) { 
 
    for(let i = 0; i < letters.length; i++) { 
 
    await clickLetter(letters[i]); 
 
    } 
 
} 
 

 
clickLetters(letters, clickLetter);

+0

非同期関数が終了を待つ場合、私はそれを約束の中に入れなければなりません。非同期関数に複数レベルのネストされた非同期呼び出しが含まれている場合、Promiseで各レベルをラップする必要がありますか? – Linh

+0

'setTimeout'の最初の引数のようなコールバック関数を扱うときはいつでもそうしたいでしょう。 –

1

述べたように、asyncライブラリは/それを行うための方法でした。

現在の解決策を使い続けるには、暗黙の約束がタイムアウトの直前に返されていたhandleClick()に問題がありました。次に、各パスのランダムタイムアウトに応じて、outまたはordrが実行されます。修正はただの約束を解決してからタイムアウトになります。

function handleClick(element) { 
 
    return new Promise(resolve => { 
 
    setTimeout(function(){ 
 
     console.log(`Click on Element_${element}`); 
 
     resolve(); 
 
    } 
 
    , Math.random(5)*1000); 
 
    }); 
 
} 
 

 
async function clickLetter(letter) { 
 
    await handleClick(letter); 
 
} 
 

 
function clickLetters(letters, fn) { 
 
    let index = 0; 
 
    return new Promise(function(resolve, reject) { 
 
    function next() { 
 
     if (index < letters.length) { 
 
     fn(letters[index++]).then(next, reject); 
 
     } else { 
 
     resolve(); 
 
     } 
 
    } 
 
    next(); 
 
    }); 
 
} 
 

 
const letters = ['A', 'B', 'C']; 
 
clickLetters(letters, clickLetter);

1

非同期について読むと、ここで待っています。ここで

コードです。説明は終わりです。

async function handleClick(element) { 
 
    return new Promise((resolve, reject) => { 
 
    setTimeout(function(){ 
 
     console.log(`Click on Element_${element}`); 
 
     resolve(); 
 
    }, Math.random(5)*1000); 
 
    }); 
 
} 
 

 
async function clickLetter(letter) { 
 
    await handleClick(letter); 
 
} 
 

 
async function clickGroup(group) { 
 
    await handleClick(group); 
 
} 
 

 
const letters = ['A', 'B', 'C']; 
 

 
async function clickLetters(letters, fn) { 
 
    for(let i=0; i<letters.length; i++) { 
 
    await clickLetter(letters[i]); 
 
    } 
 
} 
 

 
clickLetters(letters, clickLetter);

あなたが必要となる変更内容の説明 -

  • STEP 1からPromiseを返すために、あなたのhandleClick機能を変換します。

  • awaitclickLetters関数で使用して値を順番に印刷します。

関連する問題