首页 > 解决方案 > JS Promise:调用一个在resolve中有return语句的函数

问题描述

我有一个负责将图像上传到远程存储的功能。

我还有另一个在数据库中创建用户的函数。在创建用户的过程中,我应该上传图片,取回上传图片的URL,并将其添加到用户对象中,然后再添加到数据库中。但是,我被困在取回网址:

我上传图片的功能:

export const writePicture = (picture) => {
    if (picture !== undefined) {

       //code to upload image to database (...)

                .then((url) => {
                    console.log(`finished executing writePicture, url: ${url}`) //all good here, url is console logged.
                    return url;
                });
        });
    } else {
        console.log("finished executing writePicture")
        return ""
    };
}

上面的函数被导出到另一个我使用 Promise 的文件中。我的承诺目前设置如下:

//pictureLogo and pictureImage are existing image objects

const waitForLogoUrl = new Promise((resolve, reject) => {
  resolve(writePicture(pictureLogo));
});

const waitForImageUrl = new Promise((resolve, reject) => {
  resolve(writePicture(pictureImage));
});

Promise.all([waitForLogoUrl, waitForImageUrl]).then((urls) => {
  //urls should be an array containing the urls from first and second promise
  console.log("the urls are:");
  console.log(urls);
});

以上没有按预期工作。在里面urls,我得到一个包含两个未定义条目的数组,而不是两个获得的 url。

writePicture()工作正常,它正在上传图片和控制台记录 url。但是,在完成后,这些 url 将被控制台记录Promise.all

https://imgur.com/lvP7rrg

我不熟悉使用 Promise,所以我可能遗漏了一些关于如何在解析中调用函数的内容。任何帮助表示赞赏。

标签: javascriptpromise

解决方案


通常当new Promise出现在代码中时,它是一个危险信号,这也不例外。下面我假设你不能使用 async/await,它只纠正了两件事:

  1. 从 writePicture 返回承诺
  2. 不要不必要地将其结果包装在另一个承诺中。
export const writePicture = (picture) => {
    if (picture !== undefined) {
      return codeToUploadImage(...)   // Return is critical here
         .then((url) => {
            console.log(`finished executing writePicture, url: ${url}`) //all good here, url is console logged.
            return url;
         });
    } else {
        console.log("finished executing writePicture")
        return ""
    };
}


//pictureLogo and pictureImage are existing image objects

const waitForLogoUrl = writePicture(pictureLogo);
const waitForImageUrl = writePicture(pictureImage);

Promise.all([waitForLogoUrl, waitForImageUrl]).then((urls) => {
  //urls should be an array containing the urls from first and second promise
  console.log("the urls are:");
  console.log(urls);
})

推荐阅读