関数内の配列を関数外で使うにはどのような方法がありますか?

実際には、Google Feed Apiで取得したデータを日付でsortして最近更新のある5件を表示したいのです。つくってたら以下のようになり、当然出来なくて挫折。対処方法を初心者なので優しく教えてください。

<script>
google.load('feeds', '1');
function feeds_init(){
var rss=new Array('http://hatena.ne.jp/','http://hatena.ne.jp/');
var rssNum=rss.length+1;
var container=document.getElementById('feedControl');
var blogs=[];
for(var f=0; f < rssNum ; f++){
var feed=new google.feeds.Feed(rss[f]);
feed.setNumEntries(1);
feed.load(function(result) {
if (!result.error) {
var text='';
var entries='';
for (var i=0; i < result.feed.entries.length; i++) {
var entry=result.feed.entries[i];
text+=entry.title;
text+=entry.publishedDate;
text+=entry.contentSnippet;
entries+='<a href="'+entry.link+'">'+text+'</a>';
var entryTime=Date.parse(entry.publishedDate);
}
blogs.push(new entryData(entryTime, result.feed.title+entries));
}
});
}
blogs.sort(tmp);
for (var i=0; i < blogs.length; ++i) {
container.innerHTML+=blogs[i].data;
}
function entryData(date, data) {
this.date=date;
this.data=data;
}
function tmp(a, b){
return b[0] - a[0];
}
}
google.setOnLoadCallback(feeds_init);
</script>

回答の条件
  • 1人3回まで
  • 登録:
  • 終了:2008/06/18 09:22:07
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

ベストアンサー

id:ardarim No.3

回答回数897ベストアンサー獲得回数145

ポイント100pt

基本的に使い方は正しいと思いますし、関数内でblogs.push()したものも後でblogs.sort()したり、値を取り出したりできるはずです。


気をつけなくてはいけないのは、feed.load()は、同期実行されないということです。つまり、フィードの読み込みが終わってblogs.push()が実行される前に、for()を抜けてしまっているのです。まだblogs.push()が実行されていませんので、blogs.sort()やその後が実行されてもblogsの中身は空っぽのように見えます。

blogs.sort()などを実行した後、非同期でフィードの読み込みが終わってやっとblogs.push()が実行され、データが収まります。


こういう場合は、例えばフィードの読み込み中の数(非同期実行している数)を覚えておいて、フィードの読み込みが終わってblogs.push()するたびに -1 していく。フィードの読み込み中の数が 0 になったら(フィードを全部取得できたら)、blogs.sort()以降の処理を実行するようにするとかでいけるのではないでしょうか。

id:linyows

回答ありがとうございます。

なるほど!そういうことだったんですね。

非同期!orz

デバッグすると順番が逆になっていたので変だなと思っていたのに全く気づきませんでした。

アドバイスの通り、

読み込み数のカウントが0になり、関数にしたblogs.sort()を実行したらうまくいきました!

本当にありがとうございました!

2008/06/18 09:19:41

その他の回答2件)

id:pahoo No.1

回答回数5960ベストアンサー獲得回数633

ポイント15pt

script language の指定がありませんが、JavaScript のご質問ですよね。

たとえば、ご質問のソースの中の配列変数 rss[] を関数 feeds_init の外で使いたいということであれば、グローバル変数にすればいいでしょう。

具体的には、

var rss=new Array('http://hatena.ne.jp/','http://hatena.ne.jp/');
function feeds_init(){
  var rssNum=rss.length+1;
  ~以下省略~

のように書きます。


参考サイト

id:linyows

失礼いたしました。JavaScriptです。

説明不足だったので補足いたします。

var blogs=[];

に関数内から、以下のようにアクセス(push)して

blogs.push(new entryData(entryTime, result.feed.title+entries));

最後に

blogs.sort(tmp);

でソートしたいのです。

できない気がするので、代替方法ってありませんか?

2008/06/17 01:38:59
id:pahoo No.2

回答回数5960ベストアンサー獲得回数633

ポイント15pt

質問にあるスクリプトですと関数 entryData がどんな作用をするのか分からない(それによって関数 tmp の書き方が変わってくるはず)のですが、#1 で回答したように、配列 blogs をグローバル変数にすることで、関数 feeds_init の外部で参照・更新することはできます。


entryData の作用が分からないと書きましたが、もしかすると、blogs.push の書き方が間違っているのではないでしょうか?

blogs[i++] = new entryData(entryTime, result.feed.title+entries);

のような気もします(iの初期値はゼロ)。

id:linyows

何度もありがとうございます!

ん~なんだか分からなくなってきましたorz

つまり、FeedApiから取得した内容を一旦blogsにため込んで日付でソートしたものを表示させるつもりでスクリプトを書きました。

元は、http://code.google.com/intl/ja/apis/ajaxfeeds/documentation/hell...

を参考にしてます。

いろいろと、使い方を間違っていたらご免なさい。指摘をお願いします。

feed.load(function(result) {...}でのblogs.pushが外で有効にならないんですよね~

当たり前なのかもしれませんが。。。

よろしくお願いします。

2008/06/17 10:48:02
id:ardarim No.3

回答回数897ベストアンサー獲得回数145ここでベストアンサー

ポイント100pt

基本的に使い方は正しいと思いますし、関数内でblogs.push()したものも後でblogs.sort()したり、値を取り出したりできるはずです。


気をつけなくてはいけないのは、feed.load()は、同期実行されないということです。つまり、フィードの読み込みが終わってblogs.push()が実行される前に、for()を抜けてしまっているのです。まだblogs.push()が実行されていませんので、blogs.sort()やその後が実行されてもblogsの中身は空っぽのように見えます。

blogs.sort()などを実行した後、非同期でフィードの読み込みが終わってやっとblogs.push()が実行され、データが収まります。


こういう場合は、例えばフィードの読み込み中の数(非同期実行している数)を覚えておいて、フィードの読み込みが終わってblogs.push()するたびに -1 していく。フィードの読み込み中の数が 0 になったら(フィードを全部取得できたら)、blogs.sort()以降の処理を実行するようにするとかでいけるのではないでしょうか。

id:linyows

回答ありがとうございます。

なるほど!そういうことだったんですね。

非同期!orz

デバッグすると順番が逆になっていたので変だなと思っていたのに全く気づきませんでした。

アドバイスの通り、

読み込み数のカウントが0になり、関数にしたblogs.sort()を実行したらうまくいきました!

本当にありがとうございました!

2008/06/18 09:19:41

コメントはまだありません

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません