Merge 2 custom post type posts and taxonomy terms and sort ascending

There’s way too much information in this, so much so that it’s difficult to understand your question. First, I’d like to state my understanding of what I think you are asking.

You have a hierarchical taxonomy molecules_of_the_month and 3 post types the build-in post, a CPT molecule, and a CPT resource. What I think you want is an array containing one WP_Term object followed by several WP_Post objects: the taxonomy object is the most recent category (i.e. parent=2022, child=April); those post objects would contain the two most recent molecules, 2 most recent resources, and 3 most recent posts; and those post objects would be sorted by date. The items of the array are then displayed in blocks.

With that understanding, I’d like to demonstrate the answer by using code:

/**
 *  First, let's compile an array of the things we want to display.  The
 *  posts are the easy part, so let's do those first.
 */
$mort = array();
// Go thru the post types and the number of them we want.  Can change these numbers to get more/less of each post type.
foreach(array(
    'post'      => 3,
    'molecule'  => 3,
    'resource'  => 3,
) as $post_type => $numberposts) {
    // Get the `n` most recent posts of each type.
    foreach(get_posts(array(
        // By default, returns published posts descend sorted by date.
        'numberposts'   => $numberposts,
        'post_type'     => $post_type,
    )) as $p) {
        // Save date as key so we can easily sort later.
        $mort[date('Y-m-d', get_post_datetime($p, 'date', 'gmt')->getTimestamp()).'-0'] = $p;
    }
}

/**
 *  Time to query taxonomies.  We have to look at the name of the term because the
 *  user might assign "January" and "1981" to a "molecule" post dated 15 October 2021
 *  with the intention it be a molecule of the month in Jan '81.
 */
foreach($mort as $p) {
    // Grab the post's molecules_of_the_month terms
    $terms = get_the_terms($p, 'molecules_of_the_month');
    // Check is required as might be FALSE or WP_Error.
    if(is_array($terms)) {
        // Look at all the terms (could be empty if a 'resource' or
        // 'post' in which case this foreach-block will not execute).
        foreach($terms as $term) {
            if(!empty($term->parent)) {
            // We found a month MOTM term.  The post might have a publish date in
            // a different month, so it is necessary to generate a key for sorting
            // from the term itself.
            $date_str="1 ". $term->name .' '. get_term($term->parent, $term->taxonomy)->name;
            $date_str = date('Y-m-t', strtotime($date_str));
            $mort[$date_str.'-1'] = $term;
            }
        }
    }
}

/**
 *  All done adding stuff to the array.  It's now time to sort this big pile
 *  of goop.  As we saved each object in a key having a specially formatted
 *  date, all we need to do is sort by that key.  We want the most recently
 *  dated object to be at index=0, so we key sort decending.
 *
 *  A word on our date keys:  they are in YYYY-MM-DD format.  Also, notice
 *  the -0 and -1 appended to the end of the date (0 for posts, 1 for terms)?
 *  That's so taxonomies are sorted closer to index=0 than posts.  (Rather have
 *  posts be given priority:  change -0 suffix to -1 on line 21; change
 *  -1 suffix to -0 on line 43; and change the "Y-m-t" to "Y-m-01" on line 43.
 */
krsort($mort);

/**
 *  Now that we have our array of data, its time to display.  For
 *  simplicity, let's create two functions for HTML output:  one to
 *  output a term; and another to output a post.
 */
if(!function_exists('mort_output_term_block')) { // Protection
function mort_output_term_block($term) {
    ?><a href="<?php echo get_term_link($term); ?>"><?php 
        //get featured image
        $featured_image = get_field('tax_featured_image', $term);
        if($featured_image) {
            ?><figure class="post-featured-image">
                <?php echo wp_get_attachment_image($featured_image, 'full'); ?>
            </figure><?php
        }
        ?><ul class="cat-pill-list">
            <li class="cat-pill" style="background: #38E8AD;">
                <?php _e('Molecules of the Month') ?>
            </li>
        </ul>
        <h2 class="post-grid-title"><?php echo $term->name; ?></h2>
        <?php
        $description = get_term_meta( $term, 'intro_text', true );
        if($description) {
            ?><p><?php echo wp_trim_words($description, 19); ?></p><?php
        } else {
            echo wp_trim_words(term_description($term), 19);
        }
        ?><p class="reading-time"><?php echo dh_display_read_time(); ?></p>
    </a><?php
}}
if(!function_exists('mort_output_post_block')) { // Protection
function mort_output_post_block($_post) {
    // Set the global post so we don't have to pass it to all of the
    // template functions.  Also, remember the old global post so we can
    // restored it when we're done with the output of this block.
    global $post;
    $post_saved = $post;
    $post = $_post;
    ?><a href="<?php the_permalink(); ?>">
        <figure class="post-featured-image">
            <?php the_post_thumbnail(); ?>
        </figure><?php
        switch(get_post_type($post)) {
            case 'resource':
                $cats = get_the_terms($post, 'resource_category');
                if($cats) {
                    ?><ul class="cat-pill-list"><?php
                    foreach($cats as $cat) {
                        $text_color = get_field('cat_text_color', $cat);
                        $cat_color = get_field('category_color', $cat);
                        ?><li class="cat-pill <?php echo $text_color; ?>" style="background: <?php echo $cat_color; ?>;">
                            <?php echo $cat->name; ?>
                        </li><?php
                    }
                    ?></ul><?php
                }
                break;
            case 'molecule':
                ?><ul class="cat-pill-list">
                    <li class="cat-pill" style="background: #38E8AD;">
                        <?php _e('Molecules of the Month'); ?>
                    </li>
                </ul><?php
                break;
            default:
                ?><ul class="cat-pill-list">
                    <li class="cat-pill light" style="background: #EB546B">
                        <?php _e('Article'); ?>
                    </li>
                </ul><?php        
        }
        ?><h2 class="post-grid-title"><?php the_title(); ?></h2>
        <?php echo dh_excerpt(); ?>
        <p class="reading-time"><?php echo dh_display_read_time(); ?></p>
    </a><?php
    // Restore the global post
    $post = $post_saved;
}}

/**
 *  Now that we're all setup, it's finally time for the big show!  Let's
 *  display the blocks!
 */
// Create id attribute allowing for custom "anchor" value.
$id = 'highlights-' . $block['id'];
if( !empty($block['anchor']) ) {
    $id = $block['anchor'];
}
// Create class attribute allowing for custom "className" and "align" values.
$className="block-highlights ";
if( !empty($block['className']) ) {
    $className .= ' ' . $block['className'];
}
if( !empty($block['align']) ) {
    $className .= ' align' . $block['align'];
}
?><div id="<?php echo esc_attr($id); ?>" class="<?php echo esc_attr($className); ?>"><?php
if($mort) {
    ?><div class="slider mobile-slider splide" data-splide="{ "type" : "loop", "perPage": "3", "arrows": 0, "breakpoints": { "99999": { "destroy": 1 }, "767": { "perPage": "1" } } }">
        <div class="splide__track">
            <ul class="post-grid splide__list">
            <?php
            foreach($mort as $display_me) {
                ?><li class="post-grid-post splide__slide"><?php
                // Each object is displayed depending on what it is.
                switch(get_class($display_me)) {
                    // It's a term!
                    case 'WP_Term':
                        mort_output_term_block($display_me);
                        break;
                    // It's a post!
                    case 'WP_Post':
                    default:
                        mort_output_post_block($display_me);
                }
                ?></li><?php
            }
            ?></ul>
        </div>
    </div><?php
}
?></div>

The only lingering question in my mind is how your child taxonomy is sorted by month. I just used the arguments you provided. But on the surface, without the use of any filters, it seems as though the child taxonomy won’t be sorted as expected. Instead, if the name of the month as saved as the taxonomy name, the get_terms() of the child taxonomy will return the first element in the array [ “April”, “August”, “December”, “February”, “January”, “July”, “June”, “March”, “May”, “November”, “October”, “September” ], which, in this case, is always “April”. If you’re having a problem like this, I can solve it if you provide more information about how the taxonomy of children is structured (i.e.: what is saved as name and slug; is there any sort of term metadata that identifies the month as a number; etc) and on what it is applied (in example, the molecules_of_the_month taxonomy is only applied to molecule CPTs, and you want the WP_Term object to be displayed of the most recent molecule post). I have an idea on what to do, but am unable to propose an answer without more info.

UPDATE (3/31) Thank you so much to @rhand for introducing me to the chat function and teaching me a bit about GitHub so I can fork some code. The code was updated there to reflect the discussions we had in chat where we resolved issues. After completion, the code was copied in its entirety above.