Promise这边为什么返回undefined?

问题出在哪里呢,应该怎么写呢

// 获取一个地址
function fileUrl(path) {
  let res
  getUrl(path).then(res => {
      var reader = new FileReader();
      reader.onload = (e) => {
        console.log(e.target.result) // 打印成功
        res = e.target.result
      }
      reader.readAsDataURL(res);
  })
  return res
}

temp.url = fileUrl('80c84de4-c8ef-4afe.png')
console.log(temp.url) // undefined
阅读 5.2k
6 个回答

在你的另一个问题(for循环请求接口异步怎么赋值呢?)里的回答应该可以解决这个疑惑。感觉还是对异步的理解不够,参考这两篇文章,一篇理解,一篇方法:

就这个问题来说,fileUrl() 不能直接返回 res,最多返回一个 res 的 Promise。也可通过回调来进行后续的处理过程,具体处理方式已经在上述“另一个问题”中解答。

这里根据你想返回 res 的想法,再给一个解决方案 —— 不能直接返回值,但可以返回一个容器 —— 只不过容器里什么时候有值,说不清楚,需要有检查机制(或者回到 Promise 解决方案中来)

// 获取一个地址
function fileUrl(path) {
    const res = {
        value: null
    };

    getUrl(path).then(res => {
        var reader = new FileReader();
        reader.onload = (e) => {
            console.log(e.target.result); // 打印成功
            res = e.target.result;
        };
        reader.readAsDataURL(res);
    });

    return res;
}

const res = fileUrl("80c84de4-c8ef-4afe.png");
(() => {
    const timer = setInterval(() => {
        if (res.value) {
            clearInterval(timer);
            console.log(res.value);
        }

        // 按理说这里还需要加一个超时处理,不然万一取不到值就会一直执行下去
    }, 200);
})();

说到超时,还可以再介绍一篇博客给你:处理可能超时的异步操作 - SegmentFault 思否

// 获取一个地址
async function  fileUrl(path) {
  return getUrl(path).then(res => {
      console.log(e.target.result) // 打印出了
      return e.target.result
  })
}

temp.url = await fileUrl('80c84de4-c8ef-4afe.png')
console.log(temp.url) // undefined

getUrl 是异步的,没返回之前你就return res自然是undefined

function fileUrl(path) {
  return new Promise(resolve => {
    getUrl(path).then(res => {
      var reader = new FileReader();
      reader.onload = (e) => {
        resolve(e.target.result)
      }
      reader.readAsDataURL(res);
  })
  })
}

fileUrl('80c84de4-c8ef-4afe.png').then(d => temp.url = d)
const fileUrl = async (path) => {
  return Promise((reslove, reject) => {
    getUrl(path).then(e => {
      reslove(e.target.result)
    }).catch(e => reject(e))
  })
}
fileUrl('80c84de4-c8ef-4afe.png').then(res => temp.url = res )
const temp = {url:''}
function fileUrl(path) {
    return new Promise(ressolve=>{
        getUrl(path).then(res => {
            var reader = new FileReader();
            reader.onload = (e) => {
              console.log(e.target.result) // 打印成功
              resolve(e.target.result)
            }
            reader.readAsDataURL(res);
        })
    })
  }

  fileUrl('80c84de4-c8ef-4afe.png').then(res=>{
    temp.url = res
    console.log(temp.url)
  })

两个问题

  1. 大家都提到了,就是getUrl是异步函数,直接返回就会是空,异步是在返回之后修改的res.
  2. 对多个变量用了同一个变量名,最开始有个let res ,回调里面有个then(res,这导致你的res = 改的是回调里面的 而不是外面的
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏