Есть ли способ вернуть данные из async / await в nodejs - PullRequest
0 голосов
/ 19 марта 2020

Я пытался использовать функции async / await, и моя проблема в том, что у меня есть функция asyn c, из которой мне нужно вернуть некоторые данные, и внутри нее я вложил 3 функции await, где последняя возвращает значение для Целая функция, но я не смог этого сделать, потому что последнее ожидание находится на запросе поиска от mongodb, и он возвращает только найденный элемент. Поэтому я хотел знать, есть ли какой-нибудь способ получить эти данные из этой функции ожидания.

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

1 Ответ

0 голосов
/ 19 марта 2020

Функция async ВСЕГДА возвращает обещание. Это встроено в язык, и вы не можете его изменить. Таким образом, вы никогда не сможете вернуть простое значение из функции async.

Кроме того, простой асинхронный обратный вызов в вашей функции вызывается долго ПОСЛЕ того, как функция уже вернула это обещание, поэтому вы не можете вернуть значение из функции из этого обратного вызова.

Более того, await делает что-нибудь полезное только тогда, когда вы ожидаете обещание, поэтому ваш await в этом await Employee_credential.create() не делает ничего полезного. То же самое с каждым из ваших await утверждений. Они не ждут обещаний, поэтому они не делают ничего полезного. Пожалуйста, прочитайте о том, как await на самом деле работает и используется, а не просто вставляет его, надеясь, что это решит некоторую проблему Он работает правильно только при использовании очень специфичным c способом. Вы должны изучить это.

И, наконец, вы НИКОГДА не можете возвращать асинхронно полученное значение непосредственно из функции. Javascript просто так не работает. Вам нужно будет передать возвращаемое значение с помощью обратного вызова, обещания или события.

Вам нужно будет либо пообещать все асинхронные функции в вашей родительской функции async, чтобы вы могли использовать await с их или вам нужно будет прекратить использование async/await и сообщить обратный результат с помощью обратного вызова.

Поскольку ни одна из трех ваших асинхронных операций в вашей функции напрямую не поддерживает обещания, то наименьшее количество изменений в вашем коде Рекомендуется добавить аргумент обратного вызова в вашу функцию и go традиционный метод обратного вызова для обратной передачи асинхронных результатов. Затем вы передаете обратный вызов в функцию и получаете результат внутри этого обратного вызова при его вызове.

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

Если вы хотите использовать обещания, то bcrypt, похоже, уже имеет встроенный интерфейс обещаний, если вы это сделаете НЕ передавайте ему обратный вызов, поэтому вам просто нужно обещать метод .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;
    }
}

Вы можете использовать версию асинхронного / обещания, позвонив:

register_Employee_Credential(id, req, res).then(result => {
    console.log(result);
}).catch(err => {
    console.log(err);
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...