0
for (var i = 0; i < users.length; i++) {
  if (users[i].access_token !== undefined) {
    var syncer = require('dropsite_server/dbox_sync');
    var client = dboxApp.client(users[i].access_token);
    var websites_to_sync = [];
    syncer.doSync(client, users[i].website, users[i].access_token.uid);
  }
}

syner.doSync には、いくつかの非同期関数呼び出しがあります。はい、パフォーマンス上の理由から、それらを非同期に保ちたいと思います。問題は、syncer オブジェクトが単なる参照であるため、doSync が機能している間、for ループが実行され続け、変数が変更されることです。

現在、周囲の for ループには 2 つの要素しかありません。結果は、最後の要素のみが処理されますが、1 回だけでなく、実際には 2 回処理されます。

解決策は syncer を適切なオブジェクトにすることですが、どういうわけか失敗します。syncer のコードがどのように見えるかをよりよく理解するために、ここから始めます。

/**
* This here is the sync module. User needs to provide. All this module does,
* is sync from a users dropbox to a local path
*/
var dbox = require("dbox");
var fs = require("fs");
var async = require("async");

var allow_downloads = true;
var allow_local_deletes = true;

var client = null;
var saved_sync_data = null;
var sync_data_path = global.config.sync_data_file;
var uid = null;
var remote_sync_dirs = null;

//var sync_data_file = ".dropbox_sync_data";

var errors = [];

var queue = async.queue(doTask, 1);

exports.doSync = function (clientIn, website_domain, _uid) {
    client = clientIn;
    uid = _uid; 
    sync_data_path = sync_data_path + "_" + uid;
    remote_sync_dirs = website_domain;
    async.series(
      [
        readSyncDataFile,
        startSync
      ]);
}
/**
 * Start the Sync
 * @param  dbox client This is a dbox client
*/

function startSync() {
  console.log("get remote delta for website: " + remote_sync_dirs)
  getRemoteDelta();
}
4

1 に答える 1

0

var 宣言はループに限定されず、ファイル/関数の先頭で行う必要があります

var syncer = require('dropsite_server/dbox_sync')
  , client
  , websites_to_sync = [] //what is this used for?

for (var i = 0; i < users.length; ++i) {
  if (users[i].access_token !== undefined) {
    client = dboxApp.client(users[i].access_token)
    syncer.doSync(client, users[i].website, users[i].access_token.uid);
  }
}

最後の項目が 2 回処理される理由は、doSync 関数が呼び出すたびに上書きされるモジュール レベルの変数を設定するためです。

これを修正する方法は、代わりに変数を関数に渡すことです

exports.doSync = function (client, website_domain, uid) {
  sync_data_path = sync_data_path + "_" + uid
  remote_sync_dirs = website_domain

  async.series([
      readSyncDataFile.bind(null, client, website_domain, uid) 
    , startSync.bind(null, client, website_domain, uid) 
  ])
}

function startSync(client, website_domain, uid) {
  ...
}
function readSyncDataFile(client, website_domain, uid) {
  ...
}
于 2013-07-29T03:18:14.493 に答える