【发布时间】:2020-09-11 08:15:59
【问题描述】:
通过遵循良好的answer by T.J. Crowder 到 SO 线程,我设法将异步任务循环与 Promise.all 结合起来。实际问题是,首先我想在 Promisified 函数中读取一个 excel 文件,并在第二个 Promisified 函数中读取图像文件列表。 这是执行文件读取的代码函数。
import { User } from "./types";
import * as XLSX from "xlsx";
// Loading users data from Excel Data... Id,Name,CardNo
export async function loadUsersData(usersFile: File) {
let result_users: User[] =await new Promise((resolve) => {
var reader = new FileReader();
reader.onload = function (e) {
const data = e.target.result;
const readedData = XLSX.read(data, { type: 'binary' });
const wsname = readedData.SheetNames[0];
const ws = readedData.Sheets[wsname];
/* Convert array to json*/
const parsedData = XLSX.utils.sheet_to_json(ws, { header: 1, blankrows: false });
parsedData.shift();
const users: User[] = parsedData.map((item: any) => {
const id = item[0].toString().trim();
const name = item[1].toString().trim();
const cardNo = item[2].toString().trim();
const user: User = { id, name, cardNo };
return user;
});
resolve(users);
}
reader.readAsBinaryString(usersFile)
});
return result_users;
}
//Loading Images of Users Faces to display in material table along with other user info
export async function loadUsersFaces(users: User[], facesList: FileList) {
const facesArray = Array.from(facesList)
const promises=facesArray.map(async face=>{
return await readFace(face, users);
})
let result_users: any=await Promise.all(promises);
return result_users
}
function readFace(face: File,users:User[]) {
return new Promise((resolve) => {
const reader = new FileReader();
reader.onload = function (e) {
let faceBase64String = e.target.result; //getting Base64String of image to render as custom column in material-table as https://material-table.com/#/docs/features/custom-column-rendering
users.map(user => {
if (face.name.includes(user.id) && face.name.includes(user.name)) {
let newUser={ ...user, face: faceBase64String };
console.log(`Resoling ${JSON.stringify(newUser)}`);
resolve(newUser);
}
})
}
reader.readAsDataURL(face)
});
}
这里是执行一个接一个读取文件的动作代码。
//Here is usersFile is an excel file Blob and FileList contain list of image files
export const loadUsers = (usersFile: File,faces: FileList) => (dispatch:Dispatch) => {
dispatch(actions.startCall({ callType: callTypes.list }));
usersService.loadUsersData(usersFile).then((users:any)=>{ // Don't know how to tell compiler that it's User[]
usersService.loadUsersFaces(users,faces).then((users:any)=>{
console.log(users); // Here I should have users including Base64 Strings of face images in face property
dispatch(actions.usersFetched({ totalCount:users.length, entities:users }));
})
})
};
【问题讨论】:
-
我认为您不应该在这种情况下使用 Promise.all,因为无论如何您都在等待承诺在链中完成
-
听起来你不想使用
Promise.all,因为它会并行运行所有承诺。为什么不把它们锁起来?每个都依赖于前一个,不是吗?所以promise1().then(promise2).then(promise3)等 -
哦,你想串联(一个接一个)运行promise,而不是并行(同时)?似乎是这样,因为您希望 Promise 1 的结果可用于 Promise 2 ...等
-
什么是
arrayofObjs,您在哪里调用doSomeAsyncStuff(arrayofObjs)- 和resolve(anArrayofObjs);中的anArrayofObjs- 不清楚
标签: javascript reactjs typescript promise