2016-03-26 4 views
0

私は理想的にカスタム "オブジェクト"として実行したいいくつかのJSコードを持っていますが、私はJSの性質上そうすることはできません。javascript関数/ "class"のパラメータを非同期に変更しますか?

だから私はどこかのオンラインのブログを追ってきたし、これを書かれている(エレガントおそらくないと私には思える)ソリューション:

var mongoose = require('mongoose'); 
var dbservice = function() { 
    this.connected = false; 
    this.connection_error = false; 
    this.status_messages = []; 
    this.connect = function() { 
     mongoose.connect('Laaaadeedaaaa'); 
     var db = mongoose.connection; 
     db.on('error', function() { 
      this.status_messages.push('Nooo! Connection Error'); 
      console.error.bind(console, 'Nooo! Connection Error: '); 
      this.connection_error = true; 
     }); 
     db.once('open', function() { 
      this.status_messages.push('Successfully connected to the database!'); 
      console.log('Successfully connected to the database!'); 
      this.connected = true; 
     }); 
    }; 
    //DB (db.runCommand({whatsmyuri: 1})) 
    this.createUser = function(user_in, password_in) { 
     require("./data/models/user"); 
     var User = mongoose.model('User'); 
     var newUser = new User({ username: user_in, password: password_in, date_created: Date() }); 
     newUser.save(function(err, data) { 
      if (err) { 
       this.status_messages.push('User creation error!'); 
       console.log(err); 
      } 
      else { 
       this.status_messages.push('Success!'); 
       console.log('Success:', data); 
      } 
     }); 
    }; 
}; 
module.exports = dbservice; 

私がようにこれを呼び出そう:

var cur_service = new dbservice(); 
cur_service.connect(); 
setTimeout(function() { 
    console.log("Connected!"); 
    console.log(cur_service.connected); 
},3000); 

したがって、実質的にはthis.connectが正常に実行されており、すぐに完了します(mongoose関数が非同期であるため)。約1秒後、コンソールは期待通りにSuccessfully connected to the databaseを出力します。しかし、タイマーが刻々と変化すると、cur_service.connectedはまだ偽であり、私はそれをtrueに設定して非同期関数が完全に完了したので混乱します。これは、形式が非同期戻り値では適切でないことを意味します。では、どうやってこれを解決するのですか?私が気づいていない別の構文エラーがありますか?私はちょうどiOS /デスクトップ/ C++を実際にやっているので、これは本当に新しく抽象的なものなので、js開発を始めました:P

助けてくれてありがとう!

+0

*「私は、理想的にはクラスとして実行したいJSコードをいくつか持っていますが、明らかにJSのために実行できません。」* - ごめんなさい、何ですか? – Tomalak

+0

私はあなたの最初の文を理解していません。それ以外に、あなたが最終的に達成しようとしていることは完全にはっきりしていません。 JSでの* this *の使用がおそらくあなたが慣れていたものではないことを理解する必要もあります。 –

+0

ここには多くの問題があります。'this'は、新しいオブジェクトの作成ではなく、単純な関数呼び出しであれば、' dbservice() 'に有用な値を持たないでしょう。そして、 'this'はコールバック関数では通常は保持されないので、すべてのコールバック関数で失われます。 – jfriend00

答えて

1

通常、コールバック関数は親スコープと同じthis値を持ちません。これに対処する方法はたくさんありますが、簡単な方法はを参照するのではなく、selfなどの親スコープ変数にの値を保存してから、コールバックからselfを参照することです。それの例はここにある:一般的に

var mongoose = require('mongoose'); 
var dbservice = function() { 
    var self = this; 
    this.connected = false; 
    this.connection_error = false; 
    this.status_messages = []; 
    this.connect = function(cb) { 
     mongoose.connect('Laaaadeedaaaa'); 
     var db = mongoose.connection; 
     db.on('error', function(err) { 
      // use self in here to reference the parent object 
      self.status_messages.push('Nooo! Connection Error'); 
      console.error.bind(console, 'Nooo! Connection Error: '); 
      self.connection_error = true; 
      callback(err); 
     }); 
     db.once('open', function() { 
      self.status_messages.push('Successfully connected to the database!'); 
      console.log('Successfully connected to the database!'); 
      self.connected = true; 
      // signal completion of the connection 
      callback(null); 
     }); 
    }; 
    //DB (db.runCommand({whatsmyuri: 1})) 
    this.createUser = function(user_in, password_in, callback) { 
     var self = this; 
     require("./data/models/user"); 
     var User = mongoose.model('User'); 
     var newUser = new User({ username: user_in, password: password_in, date_created: Date() }); 
     newUser.save(function(err, data) { 
      if (err) { 
       self.status_messages.push('User creation error!'); 
       console.log(err); 
      } 
      else { 
       self.status_messages.push('Success!'); 
       console.log('Success:', data); 
      } 
      callback(err, data); 
     }); 
    }; 
}; 
module.exports = dbservice; 

、私はあなたが完了コールバックに、NOTオブジェクトの状態として、引数としてバック非同期結果を伝えることにしたいと思います。これは、オブジェクトの状態が設定されているかどうか分からないためです。その時点で補完コールバックが呼び出されると、上に示したようにコールバックに補完として渡すだけでよいことがわかります。以下のようなdbserviceを呼び出すときに、新しいオブジェクトをインスタンス化する場合、これが唯一の仕事ができる

var dbservice = require('dbservice'); 
var d = new dbservice(); 
d.connect(function(err) { 
    if (!err) { 
     d.createUser("bob", "password", function(err) { 
      if (!err) { 
       // user created here 
      } 
     }); 
    } 
}); 

あなたがここにあるもう一つの問題は、あなたがコールバックを使用するかの終わりを知らせることを約束しなければならないということです非同期オペレーションであり、オペレーションがいつ行われるかについてのタイマ推測ではない。既存のコードにいくつかのコールバックを追加して一般的な概念を示しましたが、エラーを適切に返すことにも勤勉しなければなりません。

本当にこのような非同期コードを書くつもりなら、実際に約束を使う方法を学びたいと思うのですが、インターフェースを約束すると、非同期の連鎖やエラー処理をもっと簡単にすることができます直接のコールバックを取るよりも約束を返す)、最善の利点を約束する方法を学ぶ。

+0

@Imranahmed - コードにコールバックと 'self'を追加し、タイマーを使わずに安全に呼び出す方法の例を示しました。これは、一般的な概念を説明するためのコードを使った非常に単純な例です。私は個人的にそれを別に自分でデザインします。 – jfriend00

+0

多くのありがとうございます@ jfriend00 - これは間違いなく非常に有用です!私は今これを実装しようとするのを見てみましょう。 また、アドバイスをいただきありがとうございます。コールバック!私がこれをタイマーに入れた本当の理由は、コード内で正確に間違っていたものをデバッグすることだけでした。私はなぜこれがウェブサイトを動かすとき適切ではないか理解する。 –

+0

ああ、これらのコールバックは信じられないほどです!これをありがとう!私はこれらがこのような存在であることを知らなかった。 –

関連する問題