Home > Net >  Await till whole function is completed
Await till whole function is completed

Time:04-27

I wrote some code using some promise, in my case this is a convertion script which will upload files and attachements when they are converted. The convertion part is working fine, I see the expected results in the xwiki portal.

What I want is to loop though the files of a directory, do some convertions and find and collect all the image names in the file. After this is done I need to upload the page first because thats required on the xwiki side and after that I want to upload the attachements. At this moment its uploading the wrong attachements, instead of the one sof the file its uploading them from another file. The filename in both uploadImage and uploapPage is the page its uploading to.

function importDirToXWiki (filePath: string, imagePath: string){
    fs.readdir(filePath, (err, files) => {
        if (err){
            console.log(err);
        }
        files.forEach(file => {
            convertFile(space, filePath, imagePath, file);
        });
    });
};

function convertFile(directory: string, path: string, imagePath: string, filename: string){
    fs.readFile(path   "/"   filename, async function(err: any, data: { toString: () => string; }) {
        if(err) throw err;
        attachments = []
        
        //Split the lines
        let lines = data.toString().replace(/\r\n/g,'\n').split('\n');

        //Convert md to xwiki format
        lines = convertHeaders(lines);
        lines = convertLists(lines);
        lines.map(function (line, i) {
            let filename = extractUsingRegex(line, /([a-zA-Z0-9\s_\\.\-\(\):]) (.png|.jpg)/gm)
            if(filename.length > 0) attachments.push(filename);
            lines[i] = convertImageTags(line);
        });
        
        //Adding HTML support & keep XWiki format active
        lines.unshift('{{html wiki="true"}}');
        lines.push("{{/html}}");

        await postNewPage(lines.join("\n"), directory, formatFileName(filename))   

        Promise.all(attachments.map(async attachment => {
            await uploadImage(directory, formatFileName(filename), imagePath, attachment)    
        }))
        
    });
};

async function uploadImage(space: string, page: string, imagePath: string,  filename: string){  
    if(fs.existsSync(imagePath   "/"   filename)){
        let file = fs.readFileSync(imagePath   "/"   filename);
        await postNewAttachment(file, space, page, filename );
    }        
};

CodePudding user response:

You can use Node's fs/promises API to make things simpler.

I also cleaned up some non-idiomatic uses of .forEach vs .map. You were also inadvertently making attachments a global (no const or var); consider a linter such as ESLint to warn you about things like that.

const fsp = require("fs/promises");

async function importDirToXWiki(filePath: string, imagePath: string) {
  const files = await fsp.readdir(filePath);
  const conversionPromises = files.map((file) => convertFile(space, filePath, imagePath, file));
  return Promise.all(conversionPromises);
}

async function convertFile(directory: string, path: string, imagePath: string, filename: string) {
  const data = await fsp.readFile(path   filename, "utf8");

  const attachments = [];

  //Split the lines
  let lines = data.toString().replace(/\r\n/g, "\n").split("\n");

  //Convert md to xwiki format
  lines = convertHeaders(lines);
  lines = convertLists(lines);
  lines = lines.map(function (line) {
    let filename = extractUsingRegex(line, /([a-zA-Z0-9\s_\\.\-\(\):]) (.png|.jpg)/gm);
    if (filename.length > 0) attachments.push(filename);
    return convertImageTags(line);
  });

  //Adding HTML support & keep XWiki format active
  lines.unshift('{{html wiki="true"}}');
  lines.push("{{/html}}");

  await postNewPage(lines.join("\n"), directory, formatFileName(filename));
  const uploadPromises = attachments.map((attachment) =>
    uploadImage(directory, formatFileName(filename), imagePath, attachment),
  );
  return Promise.all(uploadPromises);
}

async function uploadImage(space: string, page: string, imagePath: string, filename: string) {
  let data;
  try {
    const data = await fsp.readFile(imagePath   filename);
    return await postNewAttachment(data, space, page, filename);
  } catch (err) {
    if (err.code === "ENOENT") {
      return; // "Not found", that's likely benign
    }
    throw err;
  }
}
  • Related