Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Defining async function inside promise

I am writing code for promises using .then. Now, I have decided to write it using await/async. I have called a function add_Lessons inside promise and then call another function in .then of that function. Here is my code using .then.

function create_section(sections,course_ID,i) {
return new Promise(
    (resolve) => {
        var s_duration = 0;
        var sname = sections[i].name;
        var s_obj = {
            //some object;
        }
        var section_id;
        DB.section.create(s_obj,function (err, data_s) 
        {
            if (err) return next(err);
            section_id = data_s._id;
            var lesson = sections[i].lessons;
            add_lessons(lesson,section_id,i)
            .then(function(arr){
                resolve(arr);
            })
        });
    }
);
};

This is the code using await/async.

function create_section(sections,course_ID,i) {
return new Promise(
    async function resolve() {
        var s_duration = 0;
        var sname = sections[i].name;
        var s_obj = {
           //some obj
        }
        var section_id;
        DB.section.create(s_obj,function (err, data_s) 
        {
            if (err) return next(err);
            section_id = data_s._id;
            var lesson = sections[i].lessons;
            var arr = await add_lessons(lesson,section_id,i)
            resolve(arr);
        });
    }
);
};

The code using await/async shows an error that add_lessons is unexpected identifier. So tell me how to define async function inside promise?

like image 974
akash modi Avatar asked Mar 08 '23 23:03

akash modi


1 Answers

You put async in front of a wrong function. This function should be async:

DB.section.create(s_obj,function (err, data_s) 

like this:

DB.section.create(s_obj, async function (err, data_s)

You can use await only inside of a function that has async keyword - not in all functions that are inside other functions that have async keyword.

But also what you should pass to a new Promise() constructor is a function that takes resolve as a parameter instead of a function that is itself named resolve. Instead of this:

return new Promise(
    async function resolve() {

you should use something like:

return new Promise(function (resolve, reject) {

and then also you probably should run reject instead of next(error) - so instead of:

if (err) return next(err);

you may try:

if (err) return reject(err);

if you actually want to reject the promise that is returned from the create_section() function.

You are mixing three ways of asynchronous control flow: callbacks, promises and async/await. You need to fully understand all of them to be able to combine them without problems.

I would recommend writing a wrappers that return promises for all of the functions that take callbacks, like this:

const sectionCreate = (...args) => new Promise((resolve, reject) => {
  DB.section.create(...args, (err, data) => {
    if (err) {
      return reject(err);
    }
    resolve data;
  });
});

(or you can use Bluebird's promisify for that) and now you'll be able to use that in your async/await flow easily:

async function create_section(sections, course_ID, i) {
    var s_duration = 0;
    var sname = sections[i].name;
    var s_obj = {
       //some obj
    }
    var section_id;
    var data = await sectionCreate(s_obj);
    var section_id = data_s._id;
    var lesson = sections[i].lessons;
    var arr = await add_lessons(lesson, section_id, i);
    return arr;
}

This assumes that add_lessons() returns a promise which is implied but your code but it may not be the case. You can await on promises so you can use await in front of function calls that return promises.

Note that every async function returns a promise so you don't need to do it explicitly.

like image 99
rsp Avatar answered Mar 12 '23 10:03

rsp