backbone fetch() not working

fetch returns a promise, so you want to wait until the promise is resolved. For example:

new wp.api.models.Post( { id: 1 }  ).fetch().then( console.log );

or doing something with the data:

new wp.api.models.Post( { id: 1 }  ).fetch().then( post => {
    console.log( post );
} );

To address your comment, Promises are async – so any code you want executed based on that happening would come after it’s resolution(or rejection). It’s not really possible to change the async execution to something synchronous, but you can use the alternative syntax of await which sometimes helps make usage a bit more clear. It’s essentially the same thing behind the scenes happening. Take this example, which we wrap in an anonymous async function as await can’t be used in the top-level:

( async () => {
    let post = await new wp.api.models.Post( { id: 1 }  ).fetch();

    // Do something with `post` response.
    console.log( post );
} )();

Since await is handling promise resolution things like thenables (ie .then()) are compatible. The code above is saying get the post data from the API, since it’s flagged with await it knows to wait for the promise resolution before continuing execution. It’s the same thing as the preceding code examples. The concern with communicating with the API is we have to account for different states and/or error handling. What if we make a call to the Posts API, but the user is not logged in and authenticated. What if the post ID we request doesn’t exist? In these cases, we don’t need or want code that relies on the response to be executed. Using await the error handling can easily be done with try/catch:

( async () => {
    try {
        let post = await new wp.api.models.Post( { id: 1594988 }  ).fetch();
        // Do something with `post` response.
        console.log( post );
    } catch ( error ) {
        console.error( error );
    };
} )();

Since I don’t have a post with ID 1594988 the console.log( post ); code is not executed and the error is caught and output as a console error in the catch part of the statement. Either way we look at the code – we don’t want to decouple the request and response. We want to make the request and handle the response accordingly – whether it fails or succeeds. Any extraneous code that doesn’t matter in terms of execution (ie do something while waiting for this to happen) can be done before the call or after the call if we are synchronously executing other things – or things that are non-relevant to the result of our api response could be executed in parallel, asynchronously. We could handle multiple async calls with Promise.all, which also works with await. Putting these concepts together, here’s another example where we get the post data, and the comments data from the API so we can render a page view:

async function getCommentData() {
    return await new wp.api.models.Comment( { id: 1 }  ).fetch();
}

async function getPostData() {
    return await new wp.api.models.Post( { id: 1 }  ).fetch();
}

async function getViewData() {
  let [ postData, commentData ] = await Promise.all( [
    getPostData(),
    getCommentData(),
  ] );
  return { postData, commentData };
}

getViewData().then( data => {
    let post = data.postData.content.rendered;
    let comments = data.commentData.content.rendered;
    let page = document.createElement( 'div' );
    page.innerHTML += post;
    page.innerHTML += comments;
    document.body.appendChild( page );
} );

Hopefully this helps you figure out how a few different ways you could structure your code. I’d recommend doing some further research on promises. As a note – the wp-api backbone client is handy, but I’m not entirely sure if it will stick around. Adoption of it never seemed to go far from what I could tell, and with the introduction of Gutenberg the @wordpress/api-fetch package gives you a fetch wrapper to retrieve data from the REST API, which is used in Gutenberg itself. If possible I’d suggest switching to and using that over the backbone client if you’re wanting to use fetch and promises as it’s better maintained.