2013-03-11 25 views
6

Myślę, że nie rozumiem, jak działają obietnice Q. Chcę, aby moja pierwsza obietnica rozwiązała się przed następnym, ale tak się nie dzieje. Tu jest mój kodu:Szeregowa realizacja z obietnicami 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'); }); 

Ten kod daje:

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

Mam nadzieję, że produkuje:

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

Co robię źle?

Odpowiedz

7

to działa:

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

To ma sens - po prostu wywołanie doWork bezpośrednio w then() natychmiast wystrzelić timeout, zamiast dać Q szansę czekać aż task one jest kompletna.

4

Powód jest taki, że doWork należy odwoływać się jako funkcja. Jeśli chcesz odwołać się do funkcji wewnątrz ".then", to po prostu podajesz nazwę funkcji, nie przekazujesz parametrów. Kiedy parser zobaczy .ten (doWork ("taskTwo")) uruchomi doWork ("taskTwo") ZANIM wartość .then zostanie nawet oceniona. Próbuje powiązać parametr funkcji.

W takim przypadku, jeśli zwrócisz parametr następnego zadania w rozwiązanej obietnicy poprzedniego zadania, parser wywoła funkcję doWorks z poprawnym parametrem i we właściwej kolejności.

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

Przykładowy kod przy użyciu Q i wniosek

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 

w powyższym kodzie, można zobaczyć, że zdefiniowanie 2 metody API: dostać i słupek.

Używam biblioteki request.

  • mój po metoda API, postanawia obietnicę z ciała obiektu zwróconego przez request.POST odpowiedzi()
  • mój dostać metoda API postanawia obietnicę z odpowiedzią z request.get() call

Możesz dokładnie zobaczyć, jak możesz połączyć te 2 połączenia api za pomocą obietnic.

W pierwszym następnie Zwracam drugą obietnicę, tak że mogę połączyć obietnicę.