简体   繁体   中英

Async Javascript function returns undefined

I am trying to run this function but the it keeps returning undefined when I explicitly hardcode the return value.

const splitVideo = async (sid, video, part) => {
    let framesLocation =`${process.cwd()}/${dirs.videoFrames}/${sid}_${part}`;

    console.log(fs.existsSync(framesLocation));

    if(!fs.existsSync(framesLocation)) {
        console.log("making dir");
        f.s.mkdirSync(framesLocation);
    }

    ffmpeg(video)
        .on('end', () => {
             return "done";
         })
         .on('error', (err) => {
             throw err;
         })
         .screenshots({
              timestamps: [1,2],
              filename: `${sid}_${part}/frame-%s.png`,
              folder: `${process.cwd()}/${dirs.videoFrames}`
         });
};

Please help this is very frustrating.

Your function does not return anything, thats why you are getting undefined . Wrap the ffmpeg call in new Promise(...) to be able to resolve its asynchronous result:

const splitVideo = async (sid, video, part) => {
    // ...

    return new Promise((resolve, reject) => {
        ffmpeg(video)
            .on('end', () => {
                resolve("done");
             })
            .on('error', (err) => {
                reject(err);
             })
             .screenshots({
                  timestamps: [1,2],
                  filename: `${sid}_${part}/frame-%s.png`,
                  folder: `${process.cwd()}/${dirs.videoFrames}`
             });
    };
};

const ret = await splitVideo(...);
console.log(ret);

Also note you need to await this function to be able to read the result (or get the result in then handler).

You can only await promises.

const splitVideo = async (sid, video, part) => {
// ...

const val = await new Promise((resolve, reject) => {
    ffmpeg(video)
        .on('end', () => {
            resolve("done");
         })
        .on('error', (err) => {
            reject(err);
         })
         .screenshots({
              timestamps: [1,2],
              filename: `${sid}_${part}/frame-%s.png`,
              folder: `${process.cwd()}/${dirs.videoFrames}`
         });
      //... more code using the val maybe?
      return val
  };
};

The problem is that your ffmpeg(video) function inside your splitVideo async function is asynchronous. What's happening is that your splitVideo function is being called but it's returning undefined before your ffmpeg(video) function accomplishs. What can you do to resolve this?

You already defined your splitVideo function as an async function, this allows you to use the reserved word "await". But first let's encapsulate your ffmpeg(video) function inside a promise.

const splitVideo = async (sid, video, part) => {
    //Your code
    let promise = new Promise((resolve, reject) => {
         ffmpeg(video)
            .on('end', () => {
                  resolve("done");
             })
             .on('error', (err) => {
                 reject(err);
             })
             .screenshots({
                   timestamps: [1,2],
                   filename: `${sid}_${part}/frame-%s.png`,
                   folder: `${process.cwd()}/${dirs.videoFrames}`
             });
       });
try{
    return await promise;
 }catch(err){
    return err;        
}

This should be enough for your splitVideo function, but it's importante to pay attention cause unhandled promises rejections are deprecated and in the future will terminate your node.js process. What you need to do is also add a .catch() statement to you splitVideoFunction, something like:

splitVideo.catch((err) => {//your code}).then((result) => {//Your code})

Or your can call splitVideo inside an another async function and use:

try {
    await splitVideo(video);
}catch(err){
    //Your code
}

If you have any doubt about async/await like I had, you may find this question useful. Node.JS - Can`t get async throws with try/catch blocks

I hope it helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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