0

次のコード サンプルでは、​​text_array の各ユーザーをループしながら、テキストから場所を取得しようとしています。テキストから場所を抽出した後、正しいユーザーに対応する配列に値を戻そうとしていますが、「text_array [i] is undefined」というエラーが表示されます。私はこれで何が間違っていますか?

function replace_undefined(text_array) {
    var userLocationText = {};
    for (i = 0, l = text_array.length; i < l; i++) {
        console.log(text_array[i].user);
        userLocationText[text_array[i].user] = text_array[i].location;
        var text = text_array[i].text;
        Placemaker.getPlaces(text, function (o) {
            console.log(o);
            if ($.isArray(o.match)) {
                if (o.match[0].place.name == "Europe" || o.match[0].place.name == "United States") {
                    var location = o.match[1].place.name;
                    userLocationText[text_array[i].user] = location;
                }
                if ($.isArray(o.match)) {
                    if (o.match[0].place.name !== "Europe") {
                        var location = o.match[0].place.name;
                        userLocationText[text_array[i].user] = location;
                    }
                }
            } else if (!$.isArray(o.match)) {
                var location = o.match.place.name;
                userLocationText[text_array[i].user] = location;
            }

            console.log(text_array);
        });
    }
}

}

text_array = [{
    user: a,
    user_id: b,
    date: c,
    profile_img: d,
    text: e,
    contentString: f,
    url: g,
    location: undefined
}, {
    user: a,
    user_id: b,
    date: c,
    profile_img: d,
    text: e,
    contentString: f,
    url: g,
    location: undefined
}, {
    user: a,
    user_id: b,
    date: c,
    profile_img: d,
    text: e,
    contentString: f,
    url: g,
    location: undefined
}];
4

1 に答える 1

0

言っPlacemaker.getPlacesたように、確かに非同期なので、ここに汚いクロージャーがあります:

Placemaker.getPlaces(text, (function () {
  var z = i;
  return function (o) {
    var i = z;
    ...
    console.log(text_array);
    };
})());

「i」以外の変数を使用したり、独自のコールバックで関数を抽出したりすると、よりクリーンになります。

基本的に、実行する関数を Placemaker.getPlaces の 2 番目の引数として送信する代わりに、すぐに実行される別の関数にラップします。すぐに実行されるラッピング関数は、「i」の現在の値を保存し、最初の無名関数を返します。最初の関数は、以前と同様に、準備ができたときに Placemaker.getPlaces によって使用されます。

しかし、クロージャーにより、私の "z" var は for ループ中に存在した "i" の値を保持し、ループが終了した後もずっと使用できます。

私は知っています、それはそれほど明確ではありません。

編集:まあ、このフィドルが役立つかもしれません。

于 2012-08-22T18:32:21.603 に答える