Load images one-by-one using Promises and async-await in JavaScript











up vote
0
down vote

favorite













Desired result: I want that the images (image and image2) should load one-by-one. Following is my code:







'use strict';

window.addEventListener('DOMContentLoaded', () => {
const cvs = document.querySelector('#cvs');
cvs.width = window.innerWidth;
cvs.height = window.innerHeight;
const c = cvs.getContext('2d');

let image = new Image(); // first image
image.src = 'https://images5.alphacoders.com/559/559956.jpg';
let image2 = new Image(); // second image
image2.src = 'https://www.highreshdwallpapers.com/wp-content/uploads/2013/03/Avengers-A.jpg';
let y = 0;

let loader = img => new Promise(resolve => img.onload = resolve(img, 0, y, 100, 60));
let logger = img => new Promise(resolve => img.onload = resolve(img.src + ' loaded!'));

async function loadImages() {
await logger(image).then(console.log); // this works
await logger(image2).then(console.log); // this works

await loader(image).then(c.drawImage);
y += 60;
await loader(image2).then(c.drawImage);
};

loadImages();
});

body {
margin: 0;
}

#cvs {
position: fixed;
}

<!DOCTYPE html>
<html>

<head>
<title>Page Title</title>
<link rel="stylesheet" type="text/css" href="./style.css">
</head>

<body>
<canvas id='cvs'>Canvas not supported</canvas>
<script type="text/javascript" src='./script.js'></script>
</body>

</html>







Here's my concept:




  • I create a function that returns a new Promise which resolves when the image loads and then draws it on the canvas context:

    let loader = img => new Promise(resolve => img.onload = resolve(img, 0, height, 100, 60));




  • Then, I create an asynchronous function that calls the loader for every image and draws it on canvas:

    async function loadImages() {
    // ...
    await loader(image).then(c.drawImage);
    y += 60;
    await loader(image2).then(c.drawImage);
    };




    But, for some reasons, the code isn't working. And, I get the following error: Uncaught (in promise) TypeError: Illegal invocation.



    I've tried replacing c.drawImage with:





  • c.drawImage.bind(c), as recommended in this post and,



  • c.drawImage.call, in this case, I've changed my resolve as resolve(c, img, 0, height, 100, 60)

    But, neither of them worked out!



    What I am doing wrong?











  • share|improve this question
























    • You can resolve a promise only with a single value. Passing multiple things to resolve will ignore anything but the first.
      – Bergi
      17 hours ago















    up vote
    0
    down vote

    favorite













    Desired result: I want that the images (image and image2) should load one-by-one. Following is my code:







    'use strict';

    window.addEventListener('DOMContentLoaded', () => {
    const cvs = document.querySelector('#cvs');
    cvs.width = window.innerWidth;
    cvs.height = window.innerHeight;
    const c = cvs.getContext('2d');

    let image = new Image(); // first image
    image.src = 'https://images5.alphacoders.com/559/559956.jpg';
    let image2 = new Image(); // second image
    image2.src = 'https://www.highreshdwallpapers.com/wp-content/uploads/2013/03/Avengers-A.jpg';
    let y = 0;

    let loader = img => new Promise(resolve => img.onload = resolve(img, 0, y, 100, 60));
    let logger = img => new Promise(resolve => img.onload = resolve(img.src + ' loaded!'));

    async function loadImages() {
    await logger(image).then(console.log); // this works
    await logger(image2).then(console.log); // this works

    await loader(image).then(c.drawImage);
    y += 60;
    await loader(image2).then(c.drawImage);
    };

    loadImages();
    });

    body {
    margin: 0;
    }

    #cvs {
    position: fixed;
    }

    <!DOCTYPE html>
    <html>

    <head>
    <title>Page Title</title>
    <link rel="stylesheet" type="text/css" href="./style.css">
    </head>

    <body>
    <canvas id='cvs'>Canvas not supported</canvas>
    <script type="text/javascript" src='./script.js'></script>
    </body>

    </html>







    Here's my concept:




  • I create a function that returns a new Promise which resolves when the image loads and then draws it on the canvas context:

    let loader = img => new Promise(resolve => img.onload = resolve(img, 0, height, 100, 60));




  • Then, I create an asynchronous function that calls the loader for every image and draws it on canvas:

    async function loadImages() {
    // ...
    await loader(image).then(c.drawImage);
    y += 60;
    await loader(image2).then(c.drawImage);
    };




    But, for some reasons, the code isn't working. And, I get the following error: Uncaught (in promise) TypeError: Illegal invocation.



    I've tried replacing c.drawImage with:





  • c.drawImage.bind(c), as recommended in this post and,



  • c.drawImage.call, in this case, I've changed my resolve as resolve(c, img, 0, height, 100, 60)

    But, neither of them worked out!



    What I am doing wrong?











  • share|improve this question
























    • You can resolve a promise only with a single value. Passing multiple things to resolve will ignore anything but the first.
      – Bergi
      17 hours ago













    up vote
    0
    down vote

    favorite









    up vote
    0
    down vote

    favorite












    Desired result: I want that the images (image and image2) should load one-by-one. Following is my code:







    'use strict';

    window.addEventListener('DOMContentLoaded', () => {
    const cvs = document.querySelector('#cvs');
    cvs.width = window.innerWidth;
    cvs.height = window.innerHeight;
    const c = cvs.getContext('2d');

    let image = new Image(); // first image
    image.src = 'https://images5.alphacoders.com/559/559956.jpg';
    let image2 = new Image(); // second image
    image2.src = 'https://www.highreshdwallpapers.com/wp-content/uploads/2013/03/Avengers-A.jpg';
    let y = 0;

    let loader = img => new Promise(resolve => img.onload = resolve(img, 0, y, 100, 60));
    let logger = img => new Promise(resolve => img.onload = resolve(img.src + ' loaded!'));

    async function loadImages() {
    await logger(image).then(console.log); // this works
    await logger(image2).then(console.log); // this works

    await loader(image).then(c.drawImage);
    y += 60;
    await loader(image2).then(c.drawImage);
    };

    loadImages();
    });

    body {
    margin: 0;
    }

    #cvs {
    position: fixed;
    }

    <!DOCTYPE html>
    <html>

    <head>
    <title>Page Title</title>
    <link rel="stylesheet" type="text/css" href="./style.css">
    </head>

    <body>
    <canvas id='cvs'>Canvas not supported</canvas>
    <script type="text/javascript" src='./script.js'></script>
    </body>

    </html>







    Here's my concept:




  • I create a function that returns a new Promise which resolves when the image loads and then draws it on the canvas context:

    let loader = img => new Promise(resolve => img.onload = resolve(img, 0, height, 100, 60));




  • Then, I create an asynchronous function that calls the loader for every image and draws it on canvas:

    async function loadImages() {
    // ...
    await loader(image).then(c.drawImage);
    y += 60;
    await loader(image2).then(c.drawImage);
    };




    But, for some reasons, the code isn't working. And, I get the following error: Uncaught (in promise) TypeError: Illegal invocation.



    I've tried replacing c.drawImage with:





  • c.drawImage.bind(c), as recommended in this post and,



  • c.drawImage.call, in this case, I've changed my resolve as resolve(c, img, 0, height, 100, 60)

    But, neither of them worked out!



    What I am doing wrong?











  • share|improve this question
















    Desired result: I want that the images (image and image2) should load one-by-one. Following is my code:







    'use strict';

    window.addEventListener('DOMContentLoaded', () => {
    const cvs = document.querySelector('#cvs');
    cvs.width = window.innerWidth;
    cvs.height = window.innerHeight;
    const c = cvs.getContext('2d');

    let image = new Image(); // first image
    image.src = 'https://images5.alphacoders.com/559/559956.jpg';
    let image2 = new Image(); // second image
    image2.src = 'https://www.highreshdwallpapers.com/wp-content/uploads/2013/03/Avengers-A.jpg';
    let y = 0;

    let loader = img => new Promise(resolve => img.onload = resolve(img, 0, y, 100, 60));
    let logger = img => new Promise(resolve => img.onload = resolve(img.src + ' loaded!'));

    async function loadImages() {
    await logger(image).then(console.log); // this works
    await logger(image2).then(console.log); // this works

    await loader(image).then(c.drawImage);
    y += 60;
    await loader(image2).then(c.drawImage);
    };

    loadImages();
    });

    body {
    margin: 0;
    }

    #cvs {
    position: fixed;
    }

    <!DOCTYPE html>
    <html>

    <head>
    <title>Page Title</title>
    <link rel="stylesheet" type="text/css" href="./style.css">
    </head>

    <body>
    <canvas id='cvs'>Canvas not supported</canvas>
    <script type="text/javascript" src='./script.js'></script>
    </body>

    </html>







    Here's my concept:




  • I create a function that returns a new Promise which resolves when the image loads and then draws it on the canvas context:

    let loader = img => new Promise(resolve => img.onload = resolve(img, 0, height, 100, 60));




  • Then, I create an asynchronous function that calls the loader for every image and draws it on canvas:

    async function loadImages() {
    // ...
    await loader(image).then(c.drawImage);
    y += 60;
    await loader(image2).then(c.drawImage);
    };




    But, for some reasons, the code isn't working. And, I get the following error: Uncaught (in promise) TypeError: Illegal invocation.



    I've tried replacing c.drawImage with:





  • c.drawImage.bind(c), as recommended in this post and,



  • c.drawImage.call, in this case, I've changed my resolve as resolve(c, img, 0, height, 100, 60)

    But, neither of them worked out!



    What I am doing wrong?







  • 'use strict';

    window.addEventListener('DOMContentLoaded', () => {
    const cvs = document.querySelector('#cvs');
    cvs.width = window.innerWidth;
    cvs.height = window.innerHeight;
    const c = cvs.getContext('2d');

    let image = new Image(); // first image
    image.src = 'https://images5.alphacoders.com/559/559956.jpg';
    let image2 = new Image(); // second image
    image2.src = 'https://www.highreshdwallpapers.com/wp-content/uploads/2013/03/Avengers-A.jpg';
    let y = 0;

    let loader = img => new Promise(resolve => img.onload = resolve(img, 0, y, 100, 60));
    let logger = img => new Promise(resolve => img.onload = resolve(img.src + ' loaded!'));

    async function loadImages() {
    await logger(image).then(console.log); // this works
    await logger(image2).then(console.log); // this works

    await loader(image).then(c.drawImage);
    y += 60;
    await loader(image2).then(c.drawImage);
    };

    loadImages();
    });

    body {
    margin: 0;
    }

    #cvs {
    position: fixed;
    }

    <!DOCTYPE html>
    <html>

    <head>
    <title>Page Title</title>
    <link rel="stylesheet" type="text/css" href="./style.css">
    </head>

    <body>
    <canvas id='cvs'>Canvas not supported</canvas>
    <script type="text/javascript" src='./script.js'></script>
    </body>

    </html>





    'use strict';

    window.addEventListener('DOMContentLoaded', () => {
    const cvs = document.querySelector('#cvs');
    cvs.width = window.innerWidth;
    cvs.height = window.innerHeight;
    const c = cvs.getContext('2d');

    let image = new Image(); // first image
    image.src = 'https://images5.alphacoders.com/559/559956.jpg';
    let image2 = new Image(); // second image
    image2.src = 'https://www.highreshdwallpapers.com/wp-content/uploads/2013/03/Avengers-A.jpg';
    let y = 0;

    let loader = img => new Promise(resolve => img.onload = resolve(img, 0, y, 100, 60));
    let logger = img => new Promise(resolve => img.onload = resolve(img.src + ' loaded!'));

    async function loadImages() {
    await logger(image).then(console.log); // this works
    await logger(image2).then(console.log); // this works

    await loader(image).then(c.drawImage);
    y += 60;
    await loader(image2).then(c.drawImage);
    };

    loadImages();
    });

    body {
    margin: 0;
    }

    #cvs {
    position: fixed;
    }

    <!DOCTYPE html>
    <html>

    <head>
    <title>Page Title</title>
    <link rel="stylesheet" type="text/css" href="./style.css">
    </head>

    <body>
    <canvas id='cvs'>Canvas not supported</canvas>
    <script type="text/javascript" src='./script.js'></script>
    </body>

    </html>






    javascript canvas promise async-await






    share|improve this question















    share|improve this question













    share|improve this question




    share|improve this question








    edited 15 hours ago









    JJJ

    28.9k147491




    28.9k147491










    asked 19 hours ago









    rv7

    1,5971322




    1,5971322












    • You can resolve a promise only with a single value. Passing multiple things to resolve will ignore anything but the first.
      – Bergi
      17 hours ago


















    • You can resolve a promise only with a single value. Passing multiple things to resolve will ignore anything but the first.
      – Bergi
      17 hours ago
















    You can resolve a promise only with a single value. Passing multiple things to resolve will ignore anything but the first.
    – Bergi
    17 hours ago




    You can resolve a promise only with a single value. Passing multiple things to resolve will ignore anything but the first.
    – Bergi
    17 hours ago












    1 Answer
    1






    active

    oldest

    votes

















    up vote
    0
    down vote













    Your loadImages returns undefined (since you don't return anything explicitly), so drawImage won't do anything.



    Even though it's not entirely clear what you wish to do, I have the feeling that you wanted to draw both images in this then().



    In order to do as little modifications in your code as possible, you could just return both images in an Array, then in the then iterate over this array and call drawImage on it.

    You'd also have to pass all your arguments as an array in the loader function.



    Also, note that you had a typo in img.onload = resolve(.., it should be img.onload = e => resolve(..., otherwise resolve gets called directly.



    And also remember that the onload event will fire only once, so once you awaited for it, it on't happen again (unless you force it to).






    window.addEventListener('DOMContentLoaded', () => {
    const cvs = document.querySelector('#cvs');
    cvs.width = window.innerWidth;
    cvs.height = window.innerHeight;
    const c = cvs.getContext('2d');

    let image = new Image(); // first image
    image.src = 'https://images5.alphacoders.com/559/559956.jpg';
    let image2 = new Image(); // second image
    image2.src = 'https://www.highreshdwallpapers.com/wp-content/uploads/2013/03/Avengers-A.jpg';
    let height = 0;

    let loader = img => new Promise(resolve => {
    // resolve the arguments as an Array
    img.onload = e => resolve([img, 0, height, 100, 60]);
    // force resetting the src, otherwise onload may already have fired
    img.src = img.src;
    });

    async function loadImages() {
    const a = await loader(image);
    height += 60;
    const b = await loader(image2);
    // you must return something if you it to be passed in the then()
    return [a, b];
    };

    loadImages().then(arr => {
    arr.forEach(args => c.drawImage.apply(c, args));
    }).catch(console.error);
    });

    <canvas id='cvs'>Canvas not supported</canvas>





    But if I may, your code is far from being clear... You'd probably win by being more verbose, and split your logic differently:

    First deal with loading the assets, then deal with your rendering objects (here the arguments you pass to drawImage).



    Mixing both will just make your code harder to maintain.



    Also, your variable named height would probably be better called y.






    share|improve this answer























    • For some reasons, your code is not working
      – rv7
      18 hours ago










    • No, the images are not drawn, just some scrollbars came on x and y axis
      – rv7
      18 hours ago










    • I've updated my question in order to clear my logic a bit. The code logs in the console but doesn't draws the image. Why is it so?
      – rv7
      18 hours ago










    • Sorry There was a typo I didn't spotted (onload = e =>) + Chrome fires the onload event of the second image before you do attach its handler since we await for the first image to have loaded before adding the second event handler.
      – Kaiido
      17 hours ago











    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














     

    draft saved


    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53237026%2fload-images-one-by-one-using-promises-and-async-await-in-javascript%23new-answer', 'question_page');
    }
    );

    Post as a guest
































    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    0
    down vote













    Your loadImages returns undefined (since you don't return anything explicitly), so drawImage won't do anything.



    Even though it's not entirely clear what you wish to do, I have the feeling that you wanted to draw both images in this then().



    In order to do as little modifications in your code as possible, you could just return both images in an Array, then in the then iterate over this array and call drawImage on it.

    You'd also have to pass all your arguments as an array in the loader function.



    Also, note that you had a typo in img.onload = resolve(.., it should be img.onload = e => resolve(..., otherwise resolve gets called directly.



    And also remember that the onload event will fire only once, so once you awaited for it, it on't happen again (unless you force it to).






    window.addEventListener('DOMContentLoaded', () => {
    const cvs = document.querySelector('#cvs');
    cvs.width = window.innerWidth;
    cvs.height = window.innerHeight;
    const c = cvs.getContext('2d');

    let image = new Image(); // first image
    image.src = 'https://images5.alphacoders.com/559/559956.jpg';
    let image2 = new Image(); // second image
    image2.src = 'https://www.highreshdwallpapers.com/wp-content/uploads/2013/03/Avengers-A.jpg';
    let height = 0;

    let loader = img => new Promise(resolve => {
    // resolve the arguments as an Array
    img.onload = e => resolve([img, 0, height, 100, 60]);
    // force resetting the src, otherwise onload may already have fired
    img.src = img.src;
    });

    async function loadImages() {
    const a = await loader(image);
    height += 60;
    const b = await loader(image2);
    // you must return something if you it to be passed in the then()
    return [a, b];
    };

    loadImages().then(arr => {
    arr.forEach(args => c.drawImage.apply(c, args));
    }).catch(console.error);
    });

    <canvas id='cvs'>Canvas not supported</canvas>





    But if I may, your code is far from being clear... You'd probably win by being more verbose, and split your logic differently:

    First deal with loading the assets, then deal with your rendering objects (here the arguments you pass to drawImage).



    Mixing both will just make your code harder to maintain.



    Also, your variable named height would probably be better called y.






    share|improve this answer























    • For some reasons, your code is not working
      – rv7
      18 hours ago










    • No, the images are not drawn, just some scrollbars came on x and y axis
      – rv7
      18 hours ago










    • I've updated my question in order to clear my logic a bit. The code logs in the console but doesn't draws the image. Why is it so?
      – rv7
      18 hours ago










    • Sorry There was a typo I didn't spotted (onload = e =>) + Chrome fires the onload event of the second image before you do attach its handler since we await for the first image to have loaded before adding the second event handler.
      – Kaiido
      17 hours ago















    up vote
    0
    down vote













    Your loadImages returns undefined (since you don't return anything explicitly), so drawImage won't do anything.



    Even though it's not entirely clear what you wish to do, I have the feeling that you wanted to draw both images in this then().



    In order to do as little modifications in your code as possible, you could just return both images in an Array, then in the then iterate over this array and call drawImage on it.

    You'd also have to pass all your arguments as an array in the loader function.



    Also, note that you had a typo in img.onload = resolve(.., it should be img.onload = e => resolve(..., otherwise resolve gets called directly.



    And also remember that the onload event will fire only once, so once you awaited for it, it on't happen again (unless you force it to).






    window.addEventListener('DOMContentLoaded', () => {
    const cvs = document.querySelector('#cvs');
    cvs.width = window.innerWidth;
    cvs.height = window.innerHeight;
    const c = cvs.getContext('2d');

    let image = new Image(); // first image
    image.src = 'https://images5.alphacoders.com/559/559956.jpg';
    let image2 = new Image(); // second image
    image2.src = 'https://www.highreshdwallpapers.com/wp-content/uploads/2013/03/Avengers-A.jpg';
    let height = 0;

    let loader = img => new Promise(resolve => {
    // resolve the arguments as an Array
    img.onload = e => resolve([img, 0, height, 100, 60]);
    // force resetting the src, otherwise onload may already have fired
    img.src = img.src;
    });

    async function loadImages() {
    const a = await loader(image);
    height += 60;
    const b = await loader(image2);
    // you must return something if you it to be passed in the then()
    return [a, b];
    };

    loadImages().then(arr => {
    arr.forEach(args => c.drawImage.apply(c, args));
    }).catch(console.error);
    });

    <canvas id='cvs'>Canvas not supported</canvas>





    But if I may, your code is far from being clear... You'd probably win by being more verbose, and split your logic differently:

    First deal with loading the assets, then deal with your rendering objects (here the arguments you pass to drawImage).



    Mixing both will just make your code harder to maintain.



    Also, your variable named height would probably be better called y.






    share|improve this answer























    • For some reasons, your code is not working
      – rv7
      18 hours ago










    • No, the images are not drawn, just some scrollbars came on x and y axis
      – rv7
      18 hours ago










    • I've updated my question in order to clear my logic a bit. The code logs in the console but doesn't draws the image. Why is it so?
      – rv7
      18 hours ago










    • Sorry There was a typo I didn't spotted (onload = e =>) + Chrome fires the onload event of the second image before you do attach its handler since we await for the first image to have loaded before adding the second event handler.
      – Kaiido
      17 hours ago













    up vote
    0
    down vote










    up vote
    0
    down vote









    Your loadImages returns undefined (since you don't return anything explicitly), so drawImage won't do anything.



    Even though it's not entirely clear what you wish to do, I have the feeling that you wanted to draw both images in this then().



    In order to do as little modifications in your code as possible, you could just return both images in an Array, then in the then iterate over this array and call drawImage on it.

    You'd also have to pass all your arguments as an array in the loader function.



    Also, note that you had a typo in img.onload = resolve(.., it should be img.onload = e => resolve(..., otherwise resolve gets called directly.



    And also remember that the onload event will fire only once, so once you awaited for it, it on't happen again (unless you force it to).






    window.addEventListener('DOMContentLoaded', () => {
    const cvs = document.querySelector('#cvs');
    cvs.width = window.innerWidth;
    cvs.height = window.innerHeight;
    const c = cvs.getContext('2d');

    let image = new Image(); // first image
    image.src = 'https://images5.alphacoders.com/559/559956.jpg';
    let image2 = new Image(); // second image
    image2.src = 'https://www.highreshdwallpapers.com/wp-content/uploads/2013/03/Avengers-A.jpg';
    let height = 0;

    let loader = img => new Promise(resolve => {
    // resolve the arguments as an Array
    img.onload = e => resolve([img, 0, height, 100, 60]);
    // force resetting the src, otherwise onload may already have fired
    img.src = img.src;
    });

    async function loadImages() {
    const a = await loader(image);
    height += 60;
    const b = await loader(image2);
    // you must return something if you it to be passed in the then()
    return [a, b];
    };

    loadImages().then(arr => {
    arr.forEach(args => c.drawImage.apply(c, args));
    }).catch(console.error);
    });

    <canvas id='cvs'>Canvas not supported</canvas>





    But if I may, your code is far from being clear... You'd probably win by being more verbose, and split your logic differently:

    First deal with loading the assets, then deal with your rendering objects (here the arguments you pass to drawImage).



    Mixing both will just make your code harder to maintain.



    Also, your variable named height would probably be better called y.






    share|improve this answer














    Your loadImages returns undefined (since you don't return anything explicitly), so drawImage won't do anything.



    Even though it's not entirely clear what you wish to do, I have the feeling that you wanted to draw both images in this then().



    In order to do as little modifications in your code as possible, you could just return both images in an Array, then in the then iterate over this array and call drawImage on it.

    You'd also have to pass all your arguments as an array in the loader function.



    Also, note that you had a typo in img.onload = resolve(.., it should be img.onload = e => resolve(..., otherwise resolve gets called directly.



    And also remember that the onload event will fire only once, so once you awaited for it, it on't happen again (unless you force it to).






    window.addEventListener('DOMContentLoaded', () => {
    const cvs = document.querySelector('#cvs');
    cvs.width = window.innerWidth;
    cvs.height = window.innerHeight;
    const c = cvs.getContext('2d');

    let image = new Image(); // first image
    image.src = 'https://images5.alphacoders.com/559/559956.jpg';
    let image2 = new Image(); // second image
    image2.src = 'https://www.highreshdwallpapers.com/wp-content/uploads/2013/03/Avengers-A.jpg';
    let height = 0;

    let loader = img => new Promise(resolve => {
    // resolve the arguments as an Array
    img.onload = e => resolve([img, 0, height, 100, 60]);
    // force resetting the src, otherwise onload may already have fired
    img.src = img.src;
    });

    async function loadImages() {
    const a = await loader(image);
    height += 60;
    const b = await loader(image2);
    // you must return something if you it to be passed in the then()
    return [a, b];
    };

    loadImages().then(arr => {
    arr.forEach(args => c.drawImage.apply(c, args));
    }).catch(console.error);
    });

    <canvas id='cvs'>Canvas not supported</canvas>





    But if I may, your code is far from being clear... You'd probably win by being more verbose, and split your logic differently:

    First deal with loading the assets, then deal with your rendering objects (here the arguments you pass to drawImage).



    Mixing both will just make your code harder to maintain.



    Also, your variable named height would probably be better called y.






    window.addEventListener('DOMContentLoaded', () => {
    const cvs = document.querySelector('#cvs');
    cvs.width = window.innerWidth;
    cvs.height = window.innerHeight;
    const c = cvs.getContext('2d');

    let image = new Image(); // first image
    image.src = 'https://images5.alphacoders.com/559/559956.jpg';
    let image2 = new Image(); // second image
    image2.src = 'https://www.highreshdwallpapers.com/wp-content/uploads/2013/03/Avengers-A.jpg';
    let height = 0;

    let loader = img => new Promise(resolve => {
    // resolve the arguments as an Array
    img.onload = e => resolve([img, 0, height, 100, 60]);
    // force resetting the src, otherwise onload may already have fired
    img.src = img.src;
    });

    async function loadImages() {
    const a = await loader(image);
    height += 60;
    const b = await loader(image2);
    // you must return something if you it to be passed in the then()
    return [a, b];
    };

    loadImages().then(arr => {
    arr.forEach(args => c.drawImage.apply(c, args));
    }).catch(console.error);
    });

    <canvas id='cvs'>Canvas not supported</canvas>





    window.addEventListener('DOMContentLoaded', () => {
    const cvs = document.querySelector('#cvs');
    cvs.width = window.innerWidth;
    cvs.height = window.innerHeight;
    const c = cvs.getContext('2d');

    let image = new Image(); // first image
    image.src = 'https://images5.alphacoders.com/559/559956.jpg';
    let image2 = new Image(); // second image
    image2.src = 'https://www.highreshdwallpapers.com/wp-content/uploads/2013/03/Avengers-A.jpg';
    let height = 0;

    let loader = img => new Promise(resolve => {
    // resolve the arguments as an Array
    img.onload = e => resolve([img, 0, height, 100, 60]);
    // force resetting the src, otherwise onload may already have fired
    img.src = img.src;
    });

    async function loadImages() {
    const a = await loader(image);
    height += 60;
    const b = await loader(image2);
    // you must return something if you it to be passed in the then()
    return [a, b];
    };

    loadImages().then(arr => {
    arr.forEach(args => c.drawImage.apply(c, args));
    }).catch(console.error);
    });

    <canvas id='cvs'>Canvas not supported</canvas>






    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited 17 hours ago

























    answered 18 hours ago









    Kaiido

    37.1k45194




    37.1k45194












    • For some reasons, your code is not working
      – rv7
      18 hours ago










    • No, the images are not drawn, just some scrollbars came on x and y axis
      – rv7
      18 hours ago










    • I've updated my question in order to clear my logic a bit. The code logs in the console but doesn't draws the image. Why is it so?
      – rv7
      18 hours ago










    • Sorry There was a typo I didn't spotted (onload = e =>) + Chrome fires the onload event of the second image before you do attach its handler since we await for the first image to have loaded before adding the second event handler.
      – Kaiido
      17 hours ago


















    • For some reasons, your code is not working
      – rv7
      18 hours ago










    • No, the images are not drawn, just some scrollbars came on x and y axis
      – rv7
      18 hours ago










    • I've updated my question in order to clear my logic a bit. The code logs in the console but doesn't draws the image. Why is it so?
      – rv7
      18 hours ago










    • Sorry There was a typo I didn't spotted (onload = e =>) + Chrome fires the onload event of the second image before you do attach its handler since we await for the first image to have loaded before adding the second event handler.
      – Kaiido
      17 hours ago
















    For some reasons, your code is not working
    – rv7
    18 hours ago




    For some reasons, your code is not working
    – rv7
    18 hours ago












    No, the images are not drawn, just some scrollbars came on x and y axis
    – rv7
    18 hours ago




    No, the images are not drawn, just some scrollbars came on x and y axis
    – rv7
    18 hours ago












    I've updated my question in order to clear my logic a bit. The code logs in the console but doesn't draws the image. Why is it so?
    – rv7
    18 hours ago




    I've updated my question in order to clear my logic a bit. The code logs in the console but doesn't draws the image. Why is it so?
    – rv7
    18 hours ago












    Sorry There was a typo I didn't spotted (onload = e =>) + Chrome fires the onload event of the second image before you do attach its handler since we await for the first image to have loaded before adding the second event handler.
    – Kaiido
    17 hours ago




    Sorry There was a typo I didn't spotted (onload = e =>) + Chrome fires the onload event of the second image before you do attach its handler since we await for the first image to have loaded before adding the second event handler.
    – Kaiido
    17 hours ago


















     

    draft saved


    draft discarded



















































     


    draft saved


    draft discarded














    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53237026%2fload-images-one-by-one-using-promises-and-async-await-in-javascript%23new-answer', 'question_page');
    }
    );

    Post as a guest




















































































    Popular posts from this blog

    Florida Star v. B. J. F.

    Error while running script in elastic search , gateway timeout

    Adding quotations to stringified JSON object values