2015-04-02 5 views
3

Я не знаю, если я не использую метод .spread правильно при работе с Bluebird обещаний на Sails.js моделей. Вот что у меня есть:Bluebird метод обещания распространения возвращает TypeError

transactionAsync('BEGIN') 
.then(function() { 
    return Model.findOne({ id: 5) }); 
}) 
.then(function(results){ 
    if(!results) { 
     return res.notFound(); 
    } 
    crypto.randomBytes(24, function(err, buf) { 
     if(err) throw new Error(err); 
     var token = buf.toString('hex'); 
     // This is where it fails 
     return [results, token]; 
    }); 
}) 
.spread(function(results, token) { 
    // It doesn't get to log these 
    console.log(results, token); 
    ... 
}) 
... 

После возвращения [results, token] на второй .then (внутри криптографической обратного вызова), он выплевывает

[TypeError: expecting an array, a promise or a thenable] 

Я удалил остальную часть кода после .spread, так как это не это действительно актуально, и в этом случае выполнение останавливается перед возвратом ошибки.

Я просто хочу, чтобы передать переменные results и token функции внутри .spread. Что я делаю не так?

Любая помощь отличная. Благодарю.

+0

Вы уверены, что ваше исполнение останавливается на .spread()? –

+0

Да, ну, не получается выполнить код внутри '.spread()', и я уверен, что все, что находится внутри криптона, действительно выполняется, перед возвратом. Я предполагаю, что, возможно, я не должен помещать async-код, например crypto.randomBytes, в обещание? Или, возможно, просто сделайте crypto.randomBytes частью цепочки обещаний. – Lester

+0

Просто поместите некоторые console.log() и проследите, где останавливается выполнение? Здесь ваша ошибка указывает на то, что любая из функций then() или spread() не получает ожидаемых аргументов, поэтому может быть некоторые, где ваш поток возвращается как неопределенный. –

ответ

1
.then(function(results){ 
    if(!results) { 
     return res.notFound(); 
    } 
    crypto.randomBytes(24, function(err, buf) { 
     if(err) throw new Error(err); 
     var token = buf.toString('hex'); 
     // This is where it fails 
     return [results, token]; 
    }); 
}) 

неправ. Вы являетесь return int изнутри обратного вызова randomBytes, а не внутри then, поэтому ваш then просто возвращает undefined, а затем вы пытаетесь выполнить .spread. Чтобы правильно подождать randomBytes, вам нужно создать обещание для этого значения.

.then(function(results){ 
    if(!results) { 
     return res.notFound(); 
    } 

    return new Promise(function(resolve, reject){ 
     crypto.randomBytes(24, function(err, buf) { 
      if(err) return reject(new Error(err)); 
      var token = buf.toString('hex'); 
      // This is where it fails 
      resolve([results, token]); 
     }); 
    }); 
}) 
2

После возвращения [results, token] на второй .then

Это не то, что вы делаете. Вы возвращаетесь внутри криптовального обратного вызова, где это бессмысленно. Также никто не знает об этом обратном вызове, и вы на самом деле не return ничего от then callback.

Разработка программного обеспечения first rule составляет promisify базовый API, чтобы вы могли работать на чистых обещаниях.

var crypto = Promise.promisifyAll(crypto); 
// or specifically: 
var randomBytes = Promise.promisify(crypto.randomBytes); 

Теперь мы можем следовать правилу 3b и фактически возвращает (обещание) результат от затем then обратного вызова:

… 
.then(function(results) { 
    if (!results) { 
     return res.notFound(); 
    } 
    return crypto.randomBytesAsync(24) // returns a promise now! 
// ^^^^^^ 
    .then(function(buf) { 
     var token = buf.toString('hex'); 
     return [results, token]; 
    }); 
}) 
.spread(function(results, token) { 
    console.log(results, token); 
    … 
}) 
Смежные вопросы