gpt4 book ai didi

javascript - 解决嵌套在对象内部的任何数字 promise

转载 作者:行者123 更新时间:2023-11-30 15:39:42 26 4
gpt4 key购买 nike

我有一个对象,它在不同位置嵌套了 File 实例。我想递归地遍历对象,检查对象是否是 instanceof File,使用 promise 从实例创建数据 url,并仅在所有 promise 都已完成时才解析 promise已解决。

我有一个现有的函数,它返回一个 Promise 并在文件中的数据 URL 准备就绪时解析。

export const parsePhoto = (file) => {
return new Promise((resolve, reject) => {
const reader = new FileReader();

try {
reader.readAsDataURL(file);

reader.onloadend = () => {
return resolve(reader.result);
}
} catch(e) {
console.warn('Could not upload photo', e.target);
}
})
}

我有一个函数可以递归地在对象中查找 File

export const convertPhotosToBase64 = (values) => {
if (!values) return values;

const converted = Object.keys(values).reduce((acc, key) => {
if (values[key] instanceof File) {
// Do something here
acc[key] = parsePhoto(values[key]);
}

if (isArray(values[key])) {
acc[key] = values[key].map(value => {
if (typeof value === 'object' && !isArray(value)) {
return convertPhotosToBase64(value);
}

return value;
})
}

// Recurse if object
if (typeof values[key] === 'object' && !isArray(values[key])) {
acc[key] = convertPhotosToBase64(values[key]);
}

return acc;
}, values);

return converted;
}

我想保留传递的对象的现有结构()并且仅将 File 实例替换为 base64 字符串。

我也知道 Promise.all 但不确定如何在此上下文中使用它。

所有文件都已转换为 base64 字符串时,如何返回 convertPhotosToBase64 作为解析的 promise ?

最佳答案

让我们首先稍微简化一下您的函数,以减少所有这些条件的重复:

export function convertPhotosToBase64(value) {
if (typeof value !== 'object') return value;

if (value instanceof File) return parsePhoto(value);

if (isArray(value)) return value.map(convertPhotosToBase64);

return Object.keys(value).reduce((acc, key) => {
acc[key] = convertPhotosToBase64(value[key]);
return acc;
}, {});
}

现在,parsePhoto 是异步的并返回一个 promise 。这意味着整个 convertPhotosToBase64 将需要变得异步并始终返回一个 promise 。考虑到四种明显不同的情况,这实际上比听起来更简单:

export function convertPhotosToBase64(value) {
// wrap value
if (typeof value !== 'object') return Promise.resolve(value);

// already a promise
if (value instanceof File) return parsePhoto(value);

// map creates all the promises in parallel, use `Promise.all` to await them
if (isArray(value)) return Promise.all(value.map(convertPhotosToBase64));

// chain one after the other
return Object.keys(value).reduce((accP, key) =>
accP.then(acc =>
convertPhotosToBase64(value[key]).then(res => {
acc[key] = res;
return acc;
})
)
, Promise.resolve({}));
}

如果您可以并行执行所有操作(不仅是数组),您还可以将最后一种情况简化为

    return Object.keys(value).reduce((accP, key) =>
Promise.all([accP, convertPhotosToBase64(value[key])]).then([acc, res] => {
acc[key] = res;
return acc;
})
, Promise.resolve({}));

或者更好

    const keys = Object.keys(value);
return Promise.all(keys.map(key => convertPhotosToBase64(value[key])).then(results => {
const acc = {};
for (const [key, i] of keys.entries())
acc[key] = results[i];
return acc;
});

关于javascript - 解决嵌套在对象内部的任何数字 promise ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41007406/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com