1

私はプログラミングが初めてで(3か月)、ノードが非同期関数を処理する方法に問題があります(と思います)。

外部 API からメニューの GET リクエストを作成し、merchant.data.menu オブジェクト (デフォルトでは null) を新しいメニューに設定してマーチャントを更新するメソッド「addMenu」を持つ Merchant クラス オブジェクトがあります。ちょうど得た。

問題のコード:

this.addMenu = function(currentMerchant) {
  var id = currentMerchant.id;

  function  getMenu(id) {
    var deferred = Q.defer();
    var url = 'https://api.delivery.com/merchant/'+id+'/menu?client_id=xyz';

    request.get(url, function(error, response, body) {
      if(error) {
        console.log("Something went wrong with menu GET request: Status Code: " + response.statusCode);
        deferred.reject(new Error(error));
      } else if(!error && response.statusCode == 200) {
        menuObj = JSON.parse(body);
        deferred.resolve(menuObj);
      }        
    });

    return deferred.promise;
  };

  this.data.menu  = getMenu(id).then(function(currentMenu) {
    return currentMenu;
  });

  console.log(this.data.menu);
};

(this.data.menu) をログに記録すると、「{ state: 'pending' }」が表示されます。私は setTimeout を実行して物事を機能させることができますが、それは約束の目的全体を無効にしませんか? 私はこの一般的な問題に何日も悩まされてきました - それを解決するためにコールバック、遅延、約束などを掘り下げてきましたが、私の考えの中でもっと基本的な何かが欠けているのではないかと考えています.

ありがとうございました!

編集して追加:

結局のところ、私の問題の真の核心は、コールバック/プロミス内から this.data.menu にアクセスできないことであり、あらゆる種類の奇妙なことを行い、それらを this に戻そうとすることに気付きました。変数など

「var that = this;」を読んでください。クラススコープにアクセスするためのトリックで、コールバックとプロミスの試みがすべて正常に機能し、頭の中ではるかに理にかなっています。そして今では、副次的な利益として意図していた約束について、はるかに多くのことを知っています。助けてくれてありがとう!

4

2 に答える 2

-1

bluebird を使用してリクエストを約束し、次のようにすることもできます。

var Promise = require('bluebird');

var getRequest = Promise.promisify(require('http').get);

this.addMenu = function(currentMerchant) {
  var id = currentMerchant.id;

  function  getMenu(id) {
    var deferred = Q.defer();
    var url = 'https://api.delivery.com/merchant/'+id+'/menu?client_id=xyz';

    return getRequest(url);
  }

  this.data.menu  = getMenu(id)
                      .then(function(response) {
                        return JSON.parse(response.body);
                      })
                      .catch(function (err){
                        console.log("Something went wrong with menu GET request: " + err);
                      });

  console.log(this.data.menu);
};
于 2015-11-13T00:33:45.830 に答える