从异步函数返回未解析的手动创建的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;
}
新的实施方式不会被视为反模式的权利?
这两种情况都没有错。您必须返回一个Promise
,但您使用的API是基于回调的,因此在某个时候必须将其包装在手动创建的Promise
中。
然而,如果你要做的只是返回它解析到的值,那么await
在async
函数中调用Promise
是没有意义的。在这种情况下,你可以直接返回未解析的Promise
。
之后,如果在函数中不再使用await
,也可以删除async
关键字。但我会把它作为一个信号留给普通读者,返回值将是Promise
。