2013-03-11 16 views
6

私はどのように誤解していると思いますかQは約束します。私は、次のものが始まる前に解決するという、私の最初の約束が欲しいですが、それは起こっていません。ここに私のコードは次のとおりです。Qの約束を伴うシリアル実行

var Q = require('q'); 

function doWork(taskName) { 
    var deferred = Q.defer(); 
    console.log('starting', taskName); 
    setTimeout(function() { 
    console.log('done with', taskName); 
    deferred.resolve(); 
    }); 

    return deferred.promise; 
} 

doWork('task one') 
    .then(doWork('task two')) 
    .then(function() { console.log('all done'); }); 

このコードが生成します。

$ node test.js 
    starting task one 
    starting task two 
    done with task one 
    done with task two 
    all done 

を私はそれが生成することを望んでいるだろう:

$ node test.js 
    starting task one 
    done with task one 
    starting task two 
    done with task two 
    all done 

私が間違って何をしているのですか?

答えて

7

これは動作します:

doWork('task one') 
    .then(function() { 
    return doWork('task two') 
    }) 
    .then(function() { 
    console.log('all done'); 
    }); 

理にかなっていること - だけではなく、Qにtask oneが完了するまで待機する機会を与えることで、すぐにタイムアウトをオフに起動しますthen()に直接doWorkを呼び出します。

4

なぜなら、doWorkを関数として参照する必要があるからです。 '.then'の中の関数を参照したいのであれば、関数名を渡すだけで、パラメータを渡すことはありません。パーサーが.then(doWork( 'taskTwo'))を見ると、.thenが評価される前にdoWork( 'taskTwo')が実行されます。関数のパラメータをバインドしようとしています。

この場合、前のタスクの解決済みの約束で次のタスクのパラメータを返すと、パーサーは正しいパラメータで正しい順序でdoWorkを呼び出します。

var Q = require('q'); 
function doWork(taskNum) { 
    var deferred = Q.defer(); 
    console.log('starting', taskNum); 
    setTimeout(function() { 
     console.log('done with task', taskNum); 
     deferred.resolve(++taskNum); 
    }); 

    return deferred.promise; 
} 

doWork(1) 
.then(doWork) 
.then(function(lastTaskNum) { console.log('all done'); }); 
1

Q要求上記のコードで

var Q  = require('q'), 
    request = require('request'), 
    api  = {}; 


api.post = function (options) { 

    var deferred = Q.defer(); 

    request.post(options, function (error, response, body) { 
      error ? deferred.reject(error) : deferred.resolve(body); 
    }); 

    return deferred.promise; 
}; 

api.get = function (options) { 
    var deferred = Q.defer(); 

    request.post(options, function (error, response, body) { 
      error ? deferred.reject(error) : deferred.resolve(response); 
    }); 

    return deferred.promise; 
} 

api 
    .post({url: 'https://foo.com'}) 
    .then(function (body) { 
      console.log(body); 
      return api.get({url: 'http://myspace.hell'}); 
    }, function (error) { 
      //error handling logic 
    }) 
    .then(function (response) { 
      console.log(response); 
    }, function (error) { 
      //error handling logic 
    }) 
    .done(); //when you are done 

を使用してサンプルコード、私は2つのAPIのメソッドを定義することがわかります。ポストを取得します。

私はrequestライブラリを使用しています。

  • ポスト APIメソッド

    は、request.postによって返されたレスポンスオブジェクトの()
  • は私 APIメソッドを取得し、応答のとの約束を解決するとの約束を解決しますrequest.get()コール

約束を使用して、これらの2つのAPIコールをどのように連鎖させることができるかを正確に見ることができます。

最初のの場合、私は約束を連鎖できるように、2番目の約束を返します。