【问题标题】:Javascript Anti-Pattern - Returning a new Promise from async functionJavascript 反模式 - 从异步函数返回一个新的 Promise
【发布时间】:2021-12-29 06:31:58
【问题描述】:

是否从被视为反模式的异步函数返回未解析的手动创建的 Promise?

由于异步函数默认返回 Promise,构建一个 new Promise 并从同一个 async 函数返回它有点奇怪。

我有两种不同的方法,在第一种中,我怀疑我是否在做new Promise 构造函数反模式。在另一个中,我确信它是一种反模式。

第一个函数:

export default async (uri) => {
  const blob = await new Promise((resolve, reject) => {
    const xhr = new XMLHttpRequest();

    xhr.onload = function () {
      resolve(xhr.response);
    };

    xhr.onerror = function (e) {
      reject(new TypeError("Network request failed"));
    };

    xhr.responseType = "blob";
    xhr.open("GET", uri, true);
    xhr.send(null);
  });

  return blob;
};

第二个功能:

export async function uploadImageToStorage(
  imageUri,
  storageFolder = "images",
  stateObserver = undefined
) {
  const blob = await uriToBlob(imageUri);

  const imageId = blob._data.blobId;

  const storageRef = storage.ref(storageFolder).child(imageId);

  return new Promise((resolve, reject) => {
    storageRef.put(blob).on(
      "state_changed",
      stateObserver,
      function error(err) {
        blob.close();
        reject(err);
      },
      function complete() {
        blob.close();
        resolve(imageId);
      }
    );
  });
}

第一种方法实现是否被认为是反模式?

在第二个函数中,由于storageRef.put(blob).on() 不返回 Promise,我的 api 是基于回调的,我需要将其包装在 Promise 中,并在 complete() 回调中解析。如果我将其重构为:

export async function uploadImageToStorage(
  imageUri,
  storageFolder = "images",
  stateObserver = undefined
) {
  const blob = await uriToBlob(imageUri);

  const imageId = blob._data.blobId;

  const storageRef = storage.ref(storageFolder).child(imageId);

  await new Promise((resolve, reject) => {
    storageRef.put(blob).on(
      "state_changed",
      stateObserver,
      function error(err) {
        blob.close();
        reject(err);
      },
      function complete() {
        blob.close();
        resolve(imageId);
      }
    );
  });
  
  return imageId;
}

新的实现不会被视为反模式吧?

【问题讨论】:

  • 你能澄清一下你指的是什么反模式吗?也许是一个链接?
  • @Thomas 我认为反模式不必要地将 Promise 对象包装在 Promise 对象中。在我提供的代码中,我从一个标记为 async 函数的函数返回了一个 Promise 对象 - 根据定义,它强制该函数返回一个 Promise 对象。
  • 所以,new Promise(new Promise()) = anti-pattern ?

标签: javascript ecmascript-6 async-await


【解决方案1】:

这两种情况都没有错。您必须返回 Promise,但您使用的 API 是基于回调的,因此您必须在某个时候将其包装在手动创建的 Promise 中。

但是,如果您要做的只是返回解析为的值,那么在您的 async 函数中 awaiting Promise 是没有意义的。在这种情况下,您可以直接返回未解析的Promise。

之后,如果您不再在函数中使用await,您还可以删除async 关键字。但我会将它作为一个信号留给普通读者,即返回值将是Promise。

【讨论】:

    猜你喜欢
    • 2019-10-23
    • 2020-07-09
    • 1970-01-01
    • 2021-10-18
    • 2023-03-08
    • 2023-03-13
    • 2020-07-09
    • 2017-10-16
    • 1970-01-01
    相关资源
    最近更新 更多