Javascript 承诺不在表格中提供更新的数组

Javascript 承诺不在表格中提供更新的数组,javascript,promise,es6-promise,Javascript,Promise,Es6 Promise,有一个数组包含一些图像URL const imgs = [{ src:'./canvas-img1.jpg', pos: 20 }, { src: './canvas-img2.jpeg', pos: 25 }] 我试图在我的应用程序中对这些图像进行一次laod,然后将它们存储为缓存以供将来使用,这样我就不必一次又一次地加载它们。我使用这些图像在画布上绘制它们。我正在执行以下步骤 我承诺加载所有图像。Promise加载图像并将其存储到数组中 一旦承诺达成,我就把

有一个数组包含一些图像URL

const imgs = [{
    src:'./canvas-img1.jpg',
    pos: 20
}, {
    src: './canvas-img2.jpeg',
    pos: 25
}]
我试图在我的应用程序中对这些图像进行一次laod,然后将它们存储为缓存以供将来使用,这样我就不必一次又一次地加载它们。我使用这些图像在画布上绘制它们。我正在执行以下步骤

  • 我承诺加载所有图像。Promise加载图像并将其存储到数组中
  • 一旦承诺达成,我就把它们画在画布上
  • 这是我的密码

    drawCanvas(){
        let canvas = document.getElementById("timeline-canvas")
        let canvas_container = document.getElementById("canvas-container")
        let ctx = canvas.getContext("2d")
    
    
        this.loadImage().then((can_imgs)=>{
            console.log(can_imgs.length) // this is coming as array of length 0
            this.state.can_imgs.map((item, i)=>{
                let x = (item.pos * window.innerWidth)/100
                ctx.drawImage(item.img, x,0, 100, 100);
            })
        })
        ctx.save()
    }
    
    //load images only once and cache them
    loadImage = () => {
        return new Promise(resolve => {
            imgs.map((item, i)=>{
                let img1 = new Image()
                img1.src = item.src
                let x = (item.pos * window.innerWidth)/100
                img1.onload = function (e)
                {
                    can_imgs.push({img: img1, pos: item.pos})
                }
            })
            this.setState({can_imgs: can_imgs}, ()=>{
                 resolve(can_imgs)
            })
    
        })
    
    }
    

    但是当我在“那么”中控制台“can_uimgs.length”时,它会安慰0。它应该是长度为2的数组。我做错了什么

    问题是您希望
    onload
    同步调用,但它是异步调用的。因此,
    can\u imgs.push()
    最有可能发生在您将
    can\u imgs
    传递到
    resolve()
    之后

    我会尝试以下方法:

    let started = 0;
    let loaded = 0;
    
    imgs.map((item, i)=>{
       let img1 = new Image()
       img1.src = item.src
       let x = (item.pos * window.innerWidth) / 100
    
       started++
    
       img1.onload = (e) => {
          can_imgs.push({img: img1, pos: item.pos})
    
          loaded++
    
          if (started === loaded) {
             this.setState({can_imgs: can_imgs}, () => {
                resolve(can_imgs)
             })
          }
       }
    })
    
    使用
    started===loaded
    检查是否加载了所有图像,这样就可以调用
    resolve()
    ——就像在原始代码中一样


    我希望这有帮助

    Your
    然后在实际加载图像之前调用
    ——因此在触发
    img.onload
    之前

    要解决您的问题,请将每个图像包装在一个承诺中,并在最终解决loadImage承诺之前等待所有图像:

    
    loadImage=()=>{
    返回新承诺(解决=>{
    让images=imgs.map((项目,i)=>newpromise((解析)=>{
    设img1=新图像()
    img1.src=item.src
    设x=(item.pos*window.innerWidth)/100
    img1.onload=函数(e)
    {
    can_imgs.push({img:img1,pos:item.pos})
    解决()
    }
    }))
    //等待所有图像解析
    承诺。所有(图像)。然后(()=>{
    this.setState({can\u imgs:can\u imgs},()=>{
    解决(can\U imgs)
    })
    })
    })
    }