简体   繁体   English

如何解决nodejs + graphql上的异步s3解析器上传?

[英]how to resolve async s3 resolver upload on nodejs + graphql?

what i want to do is upload the image first the save the link to a user in db.我想要做的是首先上传图像,然后将链接保存到数据库中的用户。

This is my graphql resolver:这是我的 graphql 旋转变压器:

resolve: async (_root, args, { user, prisma }) => {

        ....

        const params = {
          Bucket: s3BucketName,
          Key: fileName,
          ACL: 'public-read',
          Body: file.createReadStream(),
          ContentType: file.mimetype,
        };
        return s3.putObject(params, async function (error, data) {
          if (error) {
            return {
              message: error,
              success: false,
            };
          } else {
            // user has updated
            if (user.profileImg)
              return prisma.user
                .update({
                  where: { id: Number(user.id) },
                  data: {
                    profileImg: fileName,
                  },
                })
                .then(
                  (response) => {
                    console.log('response: ', response);
                    return {
                      message: 'Success',
                      success: true,
                    };
                  },
                  (error) => {
                    return {
                      message: error,
                      success: false,
                    };
                  }
                );
            else {
              return {
                message: 'Success',
                success: true,
              };
            }
          }
        });
      },

what i want to do is return from s3, but my problem is i think it returns without this resolving and returns null so emmage and success is not returned.我想要做的是从 s3 返回,但我的问题是我认为它在没有此解决的情况下返回并返回 null 所以不返回 emmage 和成功。 how do i construct a function resolver using s3?如何使用 s3 构建 function 解析器?

You should return new Promise from your resolver, instead of making it async this way you can explicitly resolve() or reject() from within the nested callback.您应该从解析器return new Promise ,而不是通过这种方式使其async ,您可以在嵌套回调中显式resolve()reject()

resolve: (_root, args, { user, prisma }) => {
  return new Promise((resolve, reject) => {
    s3.putObject(params, async (error, data) => {

      if (error) {
        return reject({
          message: error.message,
          success: false
        });
      }

      try {
        await prisma.user.update();

        return resolve({
          message: "Success",
          success: true
        });
      } catch (e) {
        return reject({
          message: e.message,
          success: false
        });
      }

    });
  });
};

If you wanted to stay in the async/await paradigm, make a utility/promise-wrapper around s3.putObject ;如果您想保持async/await范式,请在s3.putObject周围创建一个实用程序/promise-wrapper;

function putObject(...params) {
  return new Promise((resolve, reject) => {
    s3.putObject(...params, async (error, data) => {
      if (error) {
        return reject(error);
      }

      return resolve(data);
    });
  });
}

resolve: async (_root, args, { user, prisma }) => {
  try {
    const response = await putObject(params);

    await prisma.user.update();

    return {
      message: "Success",
      success: true
    };
  } catch (error) {
    return {
      message: error.message,
      success: false
    };
  }
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM