简体   繁体   English

为什么链接承诺不起作用?

[英]why chaining the promise doesn't work?

I don't understand why this code block throws the error : 我不明白为什么这个代码块会抛出错误:

Cannot read property 'then' of undefined 无法读取未定义的属性'then'

bcrypt.genSalt(10,(err, salt) =>{
    if(err){
        console.log(err);
    }
    return bcrypt.hash(password,salt); 
}).then((hash)=>console.log(hash));

when this successfully logs the hash 当这成功记录哈希时

bcrypt.genSalt(10,(err, salt) =>{
    if(err){
        console.log(err);
    }
    bcrypt.hash(password,salt).then((hash) => console.log(hash));
});

since bcrypt.hash returns - Promise<string> shouldn't both these code blocks supposed to work(log hash) ? 因为bcrypt.hash返回 - Promise<string>不应该这两个代码块都应该工作(日志哈希)?

thanks ! 谢谢 !

The genSalt function does not return a promise (EDIT: It does when the callback is omitted). genSalt函数返回promise(编辑:当省略回调时它会执行)。 Instead it takes a callback, and whatever you return from that callback function is completely separate from the return of genSalt . 相反,它需要一个回调,无论你从该回调函数返回什么,都与genSalt的返回完全分开。 That is to say, genSalt returns undefined no matter what your callback function returns. 也就是说,无论你的回调函数返回什么, genSalt返回undefined。

So in order to get this to work, you can wrap the genSalt function into a promise like so: 所以为了使这个工作,你可以将genSalt函数包装成一个这样的承诺:

function genSaltPromise(num) {
    return new Promise((resolve, reject) => {
        bcrypt.genSalt(num, (err, salt) => {
            if (err) return reject(err);
            resolve(salt);
        })
    })
}

Then you could use it like so: 然后你就可以像这样使用它:

genSaltPromise(10).then(salt => {
    return bcrypt.hash(password, salt);
}).then(hash => {
    console.log(hash);
});

EDIT: As pointed out by @Bergi, the genSalt does return a promise when no callback is specified. 编辑:正如@Bergi所指出的,当没有指定回调时, genSalt会返回一个承诺。 So the above could be simplified to just: 所以上面的内容可以简化为:

bcrypt.genSalt(10).then(salt => {
    return bcrypt.hash(password, salt);
}).then(hash => {
    console.log(hash);
});

From the docs : 来自文档

Async methods that accept a callback, return a Promise when callback is not specified if Promise support is available. 接受回调的异步方法,如果Promise支持可用,则在未指定回调时返回Promise。

So just omit the callback and use then instead : 所以只要省略回调和使用then 改为

bcrypt.genSalt(10).then(salt => {
    return bcrypt.hash(password,salt); 
}).then(hash => {
    console.log(hash);
}, err => {
    console.log(err);
});

The first snippet fails because .then(..) is being called in the return value for genSalt(..) ; 因为第一片段失败.then(..)被调用中的返回值genSalt(..) ; based on the error message, I would say that the method does not return anything. 基于错误消息,我会说该方法不返回任何内容。

The second snippet works because you are calling is on bcrypt , which is a promise. 第二个代码段是有效的,因为你正在调用bcrypt ,这是一个承诺。

The Promise is returned by the callback function, not bcrypt.genSalt . Promise由回调函数返回,而不是bcrypt.genSalt So, then will work if chained with the callback function, not bcrypt.genSalt . 因此,如果使用回调函数链接, then它将起作用,而不是bcrypt.genSalt If you want to use then with bcrypt.genSalt , you need to wrap it in a promise. 如果你想使用thenbcrypt.genSalt ,你需要用它的承诺。 eg :- 例如: -

new Promise((resolve, reject) => {
  bcrypt.genSalt(10,(err, salt) =>{
    if(err){
        console.log(err);
    }
     resolve(bcrypt.hash(password,salt)); 
  })
}).then((hash)=>console.log(hash));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM