2015-08-18 11 views
6

Sembra che se la funzione 'risoluzione' non viene referenziata nella funzione utilizzata per creare una promessa, la promessa non è definita. Nel codice di seguito, ...Perché la 'nuova promessa (...)' restituisce 'indefinito'?

var count = 0; 
var limit = 3; 
// 
var thePromise; 
function timeout(_count) { 
    thePromise.resolve(_count); 
} 
function sendMessage() { 
    return new Promise(function(resolve, reject) { 
     if (++count > limit) { 
      reject({'Limit Exceeded': count}); 
     } 
     else { 
// With this line in place, the return value from this function 
// (expected to be a promise) is undefined 
      setTimeout(timeout.bind(null, count), 1000); 
// If the line above is replaced by this, it works as expected 
//   setTimeout(/*timeout.bind(null, count)*/function (_count) { 
//    resolve(_count); 
//   }.bind(null, count), 1000); 
     } 
    }); 
} 

function sendAnother(_count) { 
    console.log('Resolved with count %j', _count); 
    return sendMessage(); 
} 
function detectError(_error) { 
    console.log('Rejected with %s', JSON.stringify(_error)); 
    process.exit(1); 
} 
thePromise = sendMessage(); 
thePromise = thePromise.then(function (_count) { return sendAnother(_count)}, function(_error) {detectError(_error)}); 

cercando di fare la volontà di fuori della funzione che crea la promessa, si traduce in:

node-promises.js:6 
    thePromise.resolve(_count); 
      ^
TypeError: undefined is not a function 
    at timeout (node-promises.js:6:16) 
    at Timer.listOnTimeout (timers.js:110:15) 

Ma se la linea 16 è commentata e linee 18- 20 sono non commentati, l'output è:

Resolved with count 1 

.. che è quello che mi aspettavo. Cosa mi manca? Questo sta usando nodejs v0.12.2 su Windows 7, se questo fa alcuna differenza.

risposta

7

Succede a causa di questa linea:

thePromise.resolve(_count); 

non c'è resolve funzione su tale oggetto. resolve deriva dalla funzione che hai creato quando si crea un'istanza della nuova promessa:

return new Promise(function(resolve, reject) { 

commentando quella linea, e utilizzando la funzione alternativa, si sta chiamando il corretto resolve(), che fa sì che l'output desiderato. Una possibilità per risolvere questo problema potrebbe essere quella di passare la funzione di determinazione nella vostra chiamata timeout, ad esempio:

function timeout(resolve, _count) { 
    resolve(_count); 
} 

Anche se io non sono sicuro perché si vuole fare questo.


Il titolo chiede perché new Promise si restituisce undefined, quando il fatto è che non lo è. Sta effettivamente restituendo una promessa valida. È solo che resolve non è una funzione valida sull'oggetto promessa.

+2

Grazie Matt, la modifica suggerita consente di funzionare come previsto. Penso che dove ho sbagliato ho aspettato che la funzione 'resolve()' fosse memorizzata all'interno della promessa; ma sembra che sia definito solo durante la chiamata a 'then()'. –

Problemi correlati