2012-09-17 12 views
8

I alcuni problemi capire come utilizzare "q" (https://github.com/kriskowal/q) una promette libreria per JavaScript:Come faccio a fare una catena di callback con q?

var delayOne = function() { 
    setTimeout(function() { 
     return 'hi'; 
    }, 100); 
}; 

var delayTwo = function(preValue) { 
    setTimeout(function() { 
     return preValue + ' my name'; 
    }, 200); 
}; 

var delayThree = function(preValue) { 
    setTimeout(function() { 
     return preValue + ' is bodo'; 
    }, 300); 
}; 

var delayFour = function(preValue) { 
    setTimeout(function() { 
     console.log(preValue); 
    }, 400); 

}; 

Q.fcall(delayOne).then(delayTwo).then(delayThree).then(delayFour).end(); 

questo solo restituisce undefined ...

risposta

9

Il motivo si ottiene "indefinito" è perché le funzioni che si sta concatenamento non stanno tornando nulla:

var delayOne = function() { 
    setTimeout(function() { 
    return 'hi'; 
    }, 100); 
}; 

delayOne chiamate setTimeout, e non restituisce nulla (undefined).

Per raggiungere il vostro obiettivo è necessario utilizzare Q.defer:

var delayOne = function() { 
    var d = Q.defer();  
    setTimeout(function() { 
    d.resolve("HELLO"); 
    }, 100); 
    return d.promise; 
}; 

var delayTwo = function(preValue) { 
    setTimeout(function() { 
    alert(preValue); 
    }, 
    400); 
}; 

delayOne().then (delayTwo); 

http://jsfiddle.net/uzJrs/2/

+0

grazie per la soluzione. A parte questo, devo prendere la decisione se uso Q, cosa che migliorerebbe molto la mia qualità del codice dall'altra parte risulterebbe in una forte dipendenza. Hai esperienza se questo problema? – bodokaiser

+1

se usi molte chiamate asincrone concatenate, allora avrai bisogno di una libreria per sfuggire alla "Piramide del Destino" :). Personalmente preferisco asyncjs: https://github.com/caolan/async, e l'ho usato con successo su alcuni progetti di medie dimensioni. – wroniasty

12

Come wroniasty ha sottolineato, è necessario restituire una promessa da ciascuna di queste funzioni, ma si dovrebbe astratto anche qualsiasi callback orientato API (come setTimeout) il più possibile e utilizzare API che restituiscono invece le promesse.

Nel caso di setTimeout, Q fornisce già Q.delay(ms) che restituisce una promessa che verrà risolto dopo il numero specificato di millisecondi, ideale per sostituire setTimeout:

var delayOne = function() { 
    return Q.delay(100).then(function() { 
     return 'hi'; 
    }); 
}; 

var delayTwo = function(preValue) { 
    return Q.delay(200).then(function() { 
     return preValue + ' my name'; 
    }); 
}; 

var delayThree = function(preValue) { 
    return Q.delay(300).then(function() { 
     return preValue + ' is bodo'; 
    }); 
}; 

var delayFour = function(preValue) { 
    return Q.delay(400).then(function() { 
     console.log(preValue); 
    }); 
}; 

Q.fcall(delayOne).then(delayTwo).then(delayThree).then(delayFour).done(); 

(nota: end è stato sostituito con done)

Problemi correlati