【问题标题】:is there a way to return data from async/await in nodejs有没有办法从 nodejs 中的 async/await 返回数据
【发布时间】:2020-03-19 16:34:41
【问题描述】:

我试图使用 async/await 功能,但我的问题是我有一个 async 函数,我需要从中和内部返回一些数据我嵌套了 3 个 await 函数,其中最后一个返回整个函数的值,但我不能这样做,因为最后一个等待是来自 mongodb 的查找查询,它只返回找到的元素。所以我想知道是否有某种方法可以从该 await 函数获取该数据。

async register_Employee_Credential (id,req,res){   
        try{
            let employee_credential= new Employee_credential({
                employee: id,
                username: req.body.username,
                password: req.body.password
            });            
        await  bcrypt.genSalt(10,async (err,salt)=>{  //first await function
             await bcrypt.hash(employee_credential.password,salt, async (err,hash)=>{ //second await function
             if(err) console.log("error while generating salt");
             employee_credential.password = hash;
          result = await Employee_credential.create(employee_credential,async (err,result)=>{ // third await function
                if(err) 
                {
                  var errMessage = await help.Property_Validator(err);
                  return errMessage;  // this is the return message i need  
                }
            })

        })
    })
         return errMessage; //this is the final return for the calling function
        }catch(err){
            console.log("employee creditial error furthur: " + err);
        }
    }

【问题讨论】:

标签: node.js asynchronous


【解决方案1】:

async 函数总是返回一个承诺。这是语言内置的,您无法更改它。因此,您永远不能从 async 函数返回纯值。

函数中的一个普通异步回调在函数已经返回该承诺之后很长时间被调用,因此您无法从该回调中从函数返回值。

此外,await 仅在您等待承诺时才会做任何有用的事情,因此您在此 await Employee_credential.create() 中的 await 不会做任何有用的事情。与您的其他每个 await 语句相同。他们没有等待承诺,所以他们没有做任何有用的事情。请阅读await 的实际工作和使用方式,而不是仅仅将其粘贴在一些地方,希望它能解决一些问题。它仅在以非常特定的方式使用时才能正常工作。你需要了解这一点。

最后,您永远不能直接从函数返回异步检索的值。 Javascript 只是不能那样工作。您将不得不通过回调、承诺或事件来回传返回值。

您需要在 async 父函数中承诺所有异步函数,以便您可以将 await 与它们一起使用,或者您需要停止使用 async/await 并通过回调将返回结果传达回。

由于您的函数中的三个异步操作都没有直接支持 Promise,因此对您的代码所做的最少更改就是为您的函数添加一个回调参数,并采用传统的回调方法来传回异步结果。然后将回调传递给函数,并在调用时在该回调中获取结果。

register_Employee_Credential(id, req, res, callback) {
    try {
        let employee_credential = new Employee_credential({
            employee: id,
            username: req.body.username,
            password: req.body.password
        });
        bcrypt.genSalt(10, async (err, salt) => {
            if (err)  {
                console.log(err);
                return callback(err);
            }
            bcrypt.hash(employee_credential.password, salt, async (err, hash) => {
                if (err)  {
                    console.log(err);
                    return callback(err);
                }
                employee_credential.password = hash;
                Employee_credential.create(employee_credential, async (err, result) => {
                    if (err) {
                        var errMessage = help.Property_Validator(err);
                        callback(errMessage);
                    } else {
                        callback(null, result);
                    }
                })

            })
        })
    } catch (err) {
        console.log("employee creditial error furthur: " + err);
        callback(err);
    }
}

如果你想使用 Promise,那么如果你不向它传递回调,那么 bcrypt 似乎已经内置了一个 Promise 接口,所以你只需要承诺 .create() 方法并且可以这样做:

const {promisify} = require('util');

async register_Employee_Credential(id, req, res) {
    let employee_credential = new Employee_credential({
        employee: id,
        username: req.body.username,
        password: req.body.password
    });
    // promisify the create method
    Employee_credential.createP = promisify(Employee_credential.create);


    let salt = await bcrypt.genSalt(10);
    let hash = await bcrypt.hash(employee_credential.password, salt);
    employee_credential.password = hash;
    try {
        let result = await Employee_credential.createP(employee_credential);
        return result;
    } catch(err) {
        let errMessage = help.Property_Validator(err);
        throw errMessage;
    }
}

您可以通过调用来使用 async/promise 版本:

register_Employee_Credential(id, req, res).then(result => {
    console.log(result);
}).catch(err => {
    console.log(err);
});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-08-06
    • 2017-01-06
    • 2018-06-11
    • 1970-01-01
    • 1970-01-01
    • 2014-11-01
    • 1970-01-01
    • 2019-10-17
    相关资源
    最近更新 更多