0

私は個人使用のための小さな Node.js アプリを作成しています。これは、匿名 API を使用して自分の Twitter アカウント (pic.twitter.com リンク) にアップロードされた写真をサイドロードし、pic.twitter.com リンクを新しく取得した imgur に置き換えます。ツイートをリンクしてディスクに保存します。これを行うコードは次のとおりです。

var 
    jsdom   = require( 'jsdom' )
,   request = require( 'request' )
,   t_pic   = /http:\/\/pic.twitter.com\/([a-z0-9]+)/gi;

function rehostImage( match ) {
    request( match, function( e, r, b ) {
        if ( e ) throw e;
        jsdom.env(
            {
                html: b,
                scripts: ['http://code.jquery.com/jquery-1.7.2.min.js']
            }, 
            function( err, window ) {
                var $ = window.jQuery;
                request.post( 
                    'http://api.imgur.com/2/upload.json', 
                    { 
                        key: 'gh10z9DFZ009876E342dfsfd34234dszSD65XRV5',
                        image:$( '.twimg' ).find( 'img' ).attr( 'src' ) 
                    }, 
                    function( data ) { 
                        return data.upload.links.original; 
                    });
            });
    });
}

var tweets = [], i = 0;

/* code to GET twitter page using "request" goes here similar to rehostImage */

/* same jsdom boilerplate as in rehostImage function goes here to get 
   the jQuery handle on the page DOM. Once we get "$"... */

$( '.tweet-text' ).each( function() { 
    i++;
    tweets[ i ] = $( this ).html();
    if( tweets[i].match( t_pic ) ) { tweets[i].replace( t_pic, rehostImage ); }
});

コードがやろうとしていることは単純です。

  1. 私のツイッターページを取得します
  2. pic.twitter.com リンクの各ツイートを解析します。
  3. そのページを取得し、DOM をトラバースし、画像の URL を見つけて、anon API を介して imgur にアップロードします

問題は、regex replace heretweets[i].replace( t_pic, rehostImage )です。replace戻り値が一致した文字列を置き換えるために使用される 2 番目のパラメーターとして関数を受け取ります。この場合、アップロード後の最終的な imgur URLdata.upload.links.originalは、私のツイートの pic.twitter.com URL を置き換えてから、ローカル ディスクに保存します。

すべてがコールバックを介して非同期で行われている場合、正規表現の置換にrehostImage戻るにはどうすればよいですか? data.upload.links.original通常のアプローチは、最後の操作である正規表現の置き換えを実行し、後で実行できるコールバックとして渡すことですがdata.upload.links.original、正規表現の置き換えがインラインで行われるため、ここでそのアプローチを適用する方法がわかりません。

ポインタはありますか?

4

1 に答える 1

1

非同期呼び出しが戻るまで置換の実行を延期したい場合は、$。deferredを使用してこれを実装できます。

これは、それをどのように使用するかの例です。おそらく、特定の動作に合わせて微調整する必要があります。

まず、遅延オブジェクトが必要です。

var deferred = $.Deferred();

次に、非同期関数はpromiseを返す必要があります。

function rehostImage( match ) {
    // snip
    return deferred.promise();
}

置換コールバックは、解決が延期されるのを待ちます。

tweets[i].replace(t_pic, function () {
    rehostImage().then(function (data) {
        // the callback you want to execute when the deferred resolves
    });
});

そして最後に、非同期関数は遅延を解決する必要があります。

function( data ) {
    deferred.resolve(data.upload.links.original); 
});
于 2012-08-06T19:56:28.040 に答える