当前位置: 首页 > 知识库问答 >
问题:

javascript - JavaScript Promise 返回数组问题怎么显示undefined呢?

巫健柏
2024-01-31

js Promise 返回数组但无法使用

该如何返回结果呢?

let element = document.querySelectorAll('.test')    let promise = new Promise((resolve,reject) => {        let imgs = []            for (var i = 0; i < element.length; i++) {                html2canvas(element[i],{                    useCORS: true,                    allowTaint: false,                    logging: true                }).then(function(canvas) {                    let ctx = canvas.getContext("2d")                    let page = document.createElement("canvas")                    page.width = canvas.width                    page.height = canvas.height                    page.getContext("2d").putImageData(ctx.getImageData(0, 0, canvas.width, canvas.height), 0, 0)                    imgs.push(page.toDataURL("image/jpeg", 1.0))                })            }            console.log(imgs,imgs.length)            resolve(imgs)        })    promise.then(e => {            console.log(e, e.length)    })

在这里打印e,可以看到是个数组,但e.length显示就是0;而且直接使用e[0]就是undefined

共有4个答案

彭弘伟
2024-01-31

Promise的传入的函数是同步执行的,你这里 resolve 放在同步阶段去触发了,拿到的 imgs 肯定还是空的,then部分注册的回调是异步流程,执行时序肯定在 resolve 之后
image.png

你这里 resolve 需要放到 then 成功的回调里面去触发,也就是楼上的解决方案

谯翔
2024-01-31

因为Promise是异步的,你需要用async/await将其变成同步的

let promise = new Promise(async (resolve,reject) => {  let imgs = []  for (var i = 0; i < 10; i++) {      await new Promise((resolve2,reject2)=>{        resolve2()      }).then(()=>{        imgs.push(i)      })  }  // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 10  console.log(imgs,imgs.length)  resolve(imgs)})promise.then(e => {    // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 10    console.log(e, e.length)})
let promise2 = new Promise((resolve,reject) => {  let imgs = []  for (var i = 0; i < 10; i++) {      new Promise((resolve2,reject2)=>{        resolve2()      }).then(()=>{        imgs.push(i)      })  }  //[] 0  console.log(imgs,imgs.length)  resolve(imgs)})promise2.then(e => {    // 这里是10个10是因为上边循环的i使用var定义的,改用let即可,不过对你原代码无所谓    // [10,10,10,10,10,10,10,10,10,10] 10    console.log(e, e.length)})
郗浩
2024-01-31

resolve(imgs)修改为

if (imgs.length === element.length) {   resolve(imgs); }

并移动到 imgs.push(page.toDataURL("image/jpeg", 1.0)) 后面

司徒钱青
2024-01-31

你的问题出在异步操作的处理上。html2canvas 函数是异步的,它会返回一个 Promise,这意味着你的 for 循环会立即执行完,然后在下一个事件循环中,所有的 html2canvas Promise 才会被解决。因此,当你在 for 循环结束后调用 resolve(imgs) 时,imgs 数组可能还没有被任何 Promise 填充。

你可以使用 Promise.all 来解决这个问题,它可以使所有的 Promise 都在一个数组中按顺序解决。这是一个修改后的版本:

let element = document.querySelectorAll('.test')let promises = [];for (var i = 0; i < element.length; i++) {  promises.push(html2canvas(element[i], {    useCORS: true,    allowTaint: false,    logging: true  }));}Promise.all(promises).then(imgs => {  console.log(imgs);  console.log(imgs.length);})

在这个版本中,Promise.all(promises) 会等待所有的 html2canvas Promise 都解决,然后返回一个包含所有结果的数组。这个数组会被传递给 .then 方法,因此你可以直接使用 imgs.length 来获取数组的长度,并且 imgs[0] 也不会是 undefined

 类似资料:
  • 为什么返回的时候只能写成return obj[checkProp]; 而不能写成return obj.checkProp;会输出Undefined

  • 问题内容: 在这里,我有一个简单的PHP脚本,它以json格式显示数据库中的一些值。 这显示很好,这是一个输出示例: 然后,当单击图像时,将调用此jquery: 但是,(标题,日期和时间)变量在警报框中显示为“未定义”。我尝试了多种方式来实现ajax调用,并且每次都发生相同的事情。这是我第一次尝试它,但是我不知道。 问题答案: 您的json字符串具有数组格式。您需要像这样访问json对象的属性 如

  • 我用的是parse.com。每个包里面都有很多钻子,每个品类里面都有很多包。 我卡住了。然后(函数(result,result2,result3)在最后一行。promise可以有多个promise,它是可变的。有没有一种方法可以写出如下内容: 谢谢!

  • 我有一个svg的xml代码,这段代码可以在edge、chrome浏览器正常打开并显示出svg绘制的内容,而当我用firefox打开的时候,页面却是一片空白,这是什么原因造成的以及如何修复使得firefox上也可以正常显示。 firefox的版本 edge上 firefox上

  • 问题内容: 我有一个定义了的元素,最终呈现到页面中: 我想访问DOM元素属性之类的。但是,我一直在努力,我还不知道为什么。经过一番搜索后,很明显这仅适用于一个文件,但除了这一页之外,我不在其他地方使用它。我说这是为了记录它: 是什么原因造成的? 问题答案: 正确的工作地点是特定的React生命周期方法,例如ComponentDidMount,ComponentDidUpdate 您不能从该方法引用