如何在node.js中处理异步应用程序中的模块

时间:2013-07-26 20:51:02

标签: javascript node.js oop

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循环只有两个元素,结果是,只有最后一个元素被处理,但不仅一次,而且实际上是两次。

解决方案是使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();
}

1 个答案:

答案 0 :(得分: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);
  }
}

最后一项处理两次的原因是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) {
  ...
}