node express | run a DOM query on a remote HTML page | stop express server | Search

The code initializes variables, maps an array of image sources to promises, and resolves them to write response bodies to files. The execution of these promises creates HTML and HTML print strings, which are then processed by a utility or framework object to generate a Markdown string.

Run example

npm run import -- "save a list of image elements"

save a list of image elements

var html = '';
var htmlPrint = '';
var requests = images.map((src) => {
    var filename = src.split('/').pop();
    return new Promise((resolve, reject) => {
        request(src, {encoding: 'binary'}, (err, res, body) => {
            if (err) {
                reject(err)
            }
            else {
                resolve(body)
            }
        });
    }).then(body => {
        return new Promise((resolve, reject) => {
            fs.writeFile(
                path.join(output, filename),
                body,
                'binary',
                function (err) {
                    if (err) reject(err);
                    else resolve({filename: filename, data: body});
                });
        })
    });
});
$.async();
Promise.all(requests).then(images => {
    images.forEach((i) => {
        var filename = i.filename.split('/').pop();
        var ext = mime.lookup(i.filename);
        html += '<img src="data:' + ext + ';base64,' + (new Buffer(i.data, 'binary')).toString('base64') + '" />';
        htmlPrint += '<li><img src="/assets/' + filename + '" /></li>\n';
    });
    $.mime({'text/markdown': 'Usage:\n\n```html\n' + htmlPrint + '\n```\nOutput:\n' + html});
}).catch(e => $.done(e));

What the code could have been:

const { promisify } = require('util');
const { join } = require('path');
const fs = require('fs');
const mime = require('mime-types');
const request = require('request');
const $ = require('magic');

// Refactor: Extract constants
const OUTPUT_DIR = 'output';
const BASE64_EXT = 'base64';

// Refactor: Extract functions
async function downloadImage(src, filename) {
  return new Promise((resolve, reject) => {
    request(src, { encoding: null }, (err, res, body) => {
      if (err) {
        reject(err);
      } else {
        resolve({ filename, data: body });
      }
    });
  });
}

async function writeImageToFile(data) {
  const { filename, data: imageData } = data;
  try {
    await promisify(fs.writeFile)(join(OUTPUT_DIR, filename), imageData, 'binary');
    return data;
  } catch (err) {
    throw err;
  }
}

async function generateHtml(images) {
  const promises = images.map((image) => {
    const filename = image.filename.split('/').pop();
    const ext = mime.lookup(image.filename);
    return new Promise((resolve, reject) => {
      const base64String = (new Buffer(image.data, 'binary')).toString('base64');
      const htmlImage = ``;
      const htmlPrint = `
  • \n`; resolve({ html: htmlImage, htmlPrint }); }); }); return Promise.all(promises); } // Refactor: Main function async function generateMarkdown(images) { try { const imagePromises = images.map((src) => downloadImage(src, src.split('/').pop())); const writtenImages = await Promise.all(imagePromises); const htmlImages = await generateHtml(writtenImages); const html = htmlImages.map((htmlImage) => htmlImage.html).join(''); const htmlPrint = htmlImages.map((htmlImage) => htmlImage.htmlPrint).join(''); const markdown = `Usage:\n\n```html\n${htmlPrint}\n```\nOutput:\n${html}`; $.mime({ 'text/markdown': markdown }); } catch (error) { $.done(error); } } // Refactor: Call main function images.forEach((src) => generateMarkdown([src]));

    Code Breakdown

    Variable Initialization

    The code initializes two variables: html and htmlPrint. Both are set to empty strings.

    Request Mapping

    The images array is mapped using the map function to create a new array of promises. For each image source src in the images array:

    1. The filename is extracted by splitting the source string by the / character and taking the last element (pop() method).
    2. A promise is created using the Promise constructor, which will be resolved or rejected based on the result of the request function.
    3. The then method is called on the promise to perform a subsequent operation.

    Execution

    The async function is called on the $. object, which is assumed to be a utility or framework object.

    The Promise.all method is called on the array of promises created in the previous step. This method returns a promise that resolves when all items in the array have resolved.

    When the promise resolves, the then method is called to process the results.

    Error Handling

    The catch method is called on the promise returned by Promise.all to handle any errors that may occur during the execution. If an error occurs, the $.done function is called with the error as an argument.