Bluebird promise spread方法返回TypeError

时间:2015-04-02 23:44:47

标签: javascript node.js promise sails.js bluebird

Sails.js 模型中使用 Bluebird 承诺时,我不知道我是否未正确使用.spread方法。这就是我所拥有的:

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之后删除了其余的代码,因为它不是真正相关的,并且在返回错误之前执行停止了。

我只想将变量resultstoken传递给.spread内的函数。我做错了什么?

任何帮助都很棒。感谢。

2 个答案:

答案 0 :(得分:2)

  

在第二个[results, token]

上返回.then

那不是你正在做的事情。你在加密回调中返回,这是无意义的。也没有人知道这个回调,你实际上也没有return来自 then回调的任何内容。

承诺开发的first rulepromisify底层API,以便您可以处理纯粹的承诺。

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

现在我们可以遵循规则3b并实际返回then回调中的(promise)结果:

…
.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);
    …
})

答案 1 :(得分: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回调内的randomBytes int,而不在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]);
        });
    });
})