2016-10-24 20 views
0

テキストファイルから行を読み込もうとしています。ファイルから1行を選択し、htmlページのdivに挿入します。その関数wordFromFile(ファイル名は)最初に完成し、appendWordは、グローバル変数chosenWordに同じ値を取得しているので、私はそれを作ることができますどのようにJQuery.when()と非同期イベントで動作しない()非同期イベントで動作しない

var chosenWord="original word"; 

function wordFromFile(fileName) { 
    $.get(fileName, function(data) { 
     var lines = data.split("\n"); 
     var lineCount = lines.length; 
     var randomIndex = Math.floor(Math.random() * ((lineCount-1) + 1)); 
     var word = lines[randomIndex]; 
     window.chosenWord = word; 
     console.log("wordFromFile: "+chosenWord); 
    }); 
} 

function setRandomWord() { 
    $.when(wordFromFile("http://mypage.com/words.txt")).then(appendWord()); 
} 

function appendWord() { 
    console.log("appendWord: "+window.chosenWord); 
    $('.word').text(window.chosenWord); 
} 

$(function() { 
    if($('body').is('.playpage')) { 
    setRandomWord(); 
    } 

}); 


console shows: 
appendWord: original word 
wordFromFile: particle //when i refresh the page this word changes but appendWord is always "original word" 

?なぜ私のコードでwhen()とthen()関数が動作しないのか分かりません。

+0

wordFromFileはPromiseを返しません。実際には何も返しません。$ .whenは 'undefined'ではなく、Promisesで動作します。 –

答えて

0

wordFromFile()で約束を返さなければなりません。

function wordFromFile(fileName) { 
    return $.get(fileName).then(function(data) { 
     var lines = data.split("\n"); 
     var lineCount = lines.length; 
     var randomIndex = Math.floor(Math.random() * lineCount); 
     var word = lines[randomIndex]; 
     window.chosenWord = word; 
     console.log("wordFromFile: "+chosenWord); 
     return chosenWord; 
    }); 
} 

そして、あなたが最終chosenWord値は約束の解決された値になりたい場合は、.then()ハンドラからそれを返す必要があります。また、$.get()のコールバックを.then()ハンドラに変更して、より一貫性のあるものにすることに注意してください。一般的に、約束事を使用すると、オペレーション内でそれらを一貫して使用し、約束の中に昔ながらのコールバックを混ぜることは望ましくありません。そうすることで、自動的にエラー伝搬とエラー処理機能のいくつかが破られて、提供されることになります。

function setRandomWord() { 
    wordFromFile("http://mypage.com/words.txt").then(appendWord); 
} 

要約すると::wordFromFile()はすでに約束を返し、あなたがappendWord後の括弧なし.then()への関数の参照を渡す必要があるため

その後、あなたはsetRandomWord()にまったく$.when()を使用する必要はありません

  1. 戻る012の内側に.then()ハンドラを使用しwordFromFile()
  2. から約束ではjQueryコールバックではなく、
  3. $.when()wordFromFile()を削除する必要はありません。
  4. .then()への関数参照を渡すときに、appendWordの後に括弧を削除します。あなたがそれを持っていた方法は、約束が解決したときに.then()ハンドラがいつかそれを呼び出すことを許可するのではなく、すぐにappendWordを呼び出すことでした。
  5. 最初の単語を避けようとしていない限り、あなたの乱数論理はあまり正しくありませんでした。

約束が魔法の力を持っていないことに注意してください。彼らは、内部で非同期操作が何らかの形で行われたときに「知っていない」。彼らは、非同期操作が手動で約束を解決したときに、非同期操作がいつ完了したかを知るだけです。だから、$.when()の内部に非同期操作をいくつか入れて、非同期操作が完了したときに魔法のように$.when()を知らせることはできません(多くの人がこれを試しています。代わりに、約束を$.when()に渡し、非同期操作でこれらの約束を解決する必要があります。あなたの場合、約束が1つしかないので、$.when()の必要はありません。それは、あなたが待つことを約束している複数のことがある場合にのみ必要とされます。約束があるときは、.then()と呼ぶことができます。注意すべき

他のもの:

  1. あなたは結果をバック通信するグローバル変数chosenWordを使用しています。これは必ずしも必要ではなく、一般に反パターンと見なされます。
  2. あなたのajax呼び出しでエラー処理はありません。

このコード:

$(function() { 
    if($('body').is('.playpage')) { 
    setRandomWord(); 
    } 

}); 

は、このように単純化することができます:bodyタグがそれにplaypageクラスを持っている

$(function() { 
    $("body.playpage").each(setRandomWord); 
}); 

場合、それはsetRandomWord()を呼び出します。そうでなければ、それはそれを呼び出さないでしょう。


あなたはこのようなあなたのコードからchosenWordグローバルを削除することができます:選択した単語がwordFromFile()リターンは、それがどの.then()ハンドラに渡されますので、その約束の解決された値とされる

ここ
function wordFromFile(fileName) { 
    return $.get(fileName).then(function(data) { 
     var lines = data.split("\n"); 
     var randomIndex = Math.floor(Math.random() * lines.length); 
     var word = lines[randomIndex]; 
     console.log("wordFromFile: "+word); 
     return word; 
    }); 
} 


function setRandomWord() { 
    return wordFromFile("http://mypage.com/words.txt")).then(appendWord); 
} 

function appendWord(word) { 
    console.log("appendWord: "+word); 
    $('.word').text(word); 
} 

$(function() { 
    $("body.playpage").each(setRandomWord); 
}); 

その約束を破る。 appendWord.then()ハンドラとして渡すと、その単語はappendWordに渡されます。そして、wala no globalが使用されます。

+0

本当にありがとうございます! – Prosper

+0

@Prosper - あなたがここで新しいかもしれないように見えるので、あなたの質問に答えるときは、その答えの隣にある緑色のチェックマークをクリックして最良の回答を選択する必要があります。それはどちらもあなたの質問に答えられたことをコミュニティに示し、適切な手順に従うための評判のポイントを得ることができます。 – jfriend00

関連する問題