2016-11-17 12 views
0

APIの結果をキャッシュするために必要な問題をコードで解決する必要があります。node.jsキャッシュでの同期リクエストの使用

for(var user of allUsers) { 
    var requestList = fill(cache, locations, apiUrl, cacheMap); 

    async.map(requestList, function(obj, callback) { 
     // ... 
    }, function(err, results) { 
     // PUT RESULTS INTO A CACHE 
    }); 
} 

機能fill単にlocations内の場所が存在するかどうかを確認するために、キャッシュ内に見え、それが実行される私のAPIの要求URLを作成していない:そうは次のように私はいくつかのasync.mapを持っています。

しかし、自分のコードでasync.mapをディスパッチしてすぐに次のループの繰り返しで開始するfillでキャッシュが使用されないため、キャッシュがあまり使われないことに気付いていますユーザの各反復で同期化される。

ユーザーの各反復に最後のユーザーのキャッシュの更新バージョンがあることを確認するにはどうすればよいですか。私は限られたAPIコールを非常にスマートに使用する必要があります。重複したリクエストがある場合は、一度リクエストしてから、後のリクエストでその結果をキャッシュから取得します。

私は現在、async.mapの代わりに同期要求をするしかありませんが、これはnode.jsの設計に反していることが分かります。

for(var user of allUsers) { 
    var requestList = fill(cache, locations, apiUrl, cacheMap); 

    // sync map instead 
    requestList.map(function(obj) { 
     var res = sync-request(obj) 
     // put request result into cache 
    }); 

    // cont... 
} 

答えて

1

あなただけasync.eachSeriesを使用してallUsersを反復処理することができます。これは順調に進み、非同期に保たれます。

async.eachSeries(allUsers, (user, done) => { 
    const requestList = fill(cache, locations, apiUrl, cacheMap); 

    async.map(requestList, (obj, callback) => { 
    // .. 

    callback(null, requestResult); 
    }, (err, results) => { 
    // PUT RESULTS INTO A CACHE 

    done(null, results); 
    }); 
}, cb); 
+0

シリーズを順番に実行することは保証されますか?ありがとう! –

+0

はい、保証されます。 '.each'だけを使用すると、parrallelで実行されるため、保証されません – cejast

1

使用プロミスはAPI呼び出しをプロキシしてキャッシュします。 APIリクエストのバッチ処理と結果のキャッシュは、Promisesを使用すると非常に簡単です。次の小さなコードモジュールは、既存のexpensiveAPIコールをPromiseでラップし、解決された結果を60秒間キャッシュします。

// Existing module to call the expensive API 
// using the standard callback pattern 
var expensiveApi = require("./expensiveApi"); 
// Using bluebird promise library 
// See http://bluebirdjs.com/docs/api-reference.html 
var Promise = require("bluebird"); 

// Promisify the existing callback 
expensiveApi = Promise.promisify(expensiveApi); 
// Calls to the API will now return a Promise 

// A cache for the Promises 
var cache = {}; 

module.exports = function expensiveApiWithPromises(item) { 
    // Check whether a cached Promise already exists 
    if (cache[item]) { 
    // Return it to the caller 
    return cache[item]; 
    } 

    // Promise is not in the cache 
    cache[item] = expensiveApi(item) 
    .then(function(result) { 
    // Promise has resolved 
    // set the result to expire 
    setTimeout(function() { 
     delete cache[item]; 
    }, 60 * 1000); // 60 seconds expiry 
    // Return the result 
    return result; 
    }) 
    .catch(function(err) { 
    // Promise rejected with an error 
    // Reset the cache item 
    delete cache[item]; 
    // Propagate the error 
    throw err; 
    }); 

    // Return the newly created cached Promise 
    return cache[item]; 
} 
+0

ありがとうございます! 'request()'呼び出しがこのコードでも有効であることを約束しますか?その時点で、 'request-promise()'ライブラリを使い、それに '.then()'を連鎖させたいだけではないでしょうか? –

+0

はい。あなたのAPIリクエストが 'request-promise'を使用している場合は、すでに約束を返すのでAPIリクエストを約束する必要はありません。 –

関連する問題