2 回答

TA貢獻(xiàn)1875條經(jīng)驗(yàn) 獲得超5個(gè)贊
由于承諾是異步的,因此首先執(zhí)行返回語(yǔ)句,然后將數(shù)據(jù)加載到 excel1 和 excel2 中。
case actionTypes.READ_EXCEL:
var excel1 = [];
var excel2 = [];
/*Below line will create a promise, which will be executed asynchronously.
So the execution will not wait until promise is executed.
It will go to next line which is Promise.then()*/
const promise = new Promise((resolve, reject) => {
const fileReader = new FileReader();
fileReader.readAsArrayBuffer(action.payload);
fileReader.onload = (e) => {
const bufferArray = e.target.result;
const wb = { SheetNames:[], Sheets:{} };
const ws1 = XLSX.read(bufferArray, {type: "buffer"}).Sheets.Sheet1;
const ws2 = XLSX.read(bufferArray, {type: "buffer"}).Sheets.Sheet2;
wb.SheetNames.push("Sheet1");
wb.Sheets["Sheet1"] = ws1;
wb.SheetNames.push("Sheet2");
wb.Sheets["Sheet2"] = ws2;
const data1 = XLSX.utils.sheet_to_json(ws1);
const data2 = XLSX.utils.sheet_to_json(ws2);
resolve([ data1, data2 ]);
}
fileReader.onerror = (error) => {
reject(error);
};
})
/*here as well the we're just attaching a callback to promise to be executed after promise is fulfilled. so execution will attach the specified callback (excelData arrow function) to promise.then().
And then execution will move to next line which is return statement.*/
promise.then((excelData) => {
excel1 = excelData[0];
excel2 = excelData[1];
});
/*Now here, as the promises are async and will be executed after the fileReader reads data, the values of excel1 and excel2 are not updated but only contain the empty array.
And hence your state will have empty arrays in it*/
return {
...state,
tableData: excel1,
productsData: excel2
}
default:
}
return state;
}
您可以做一件事,將使用 fileReader 讀取數(shù)據(jù)的代碼編寫到一個(gè)函數(shù)中,該函數(shù)將在您當(dāng)前在代碼中放置 dispatch 語(yǔ)句的位置執(zhí)行。在 promise.then() 中,您可以使用加載的數(shù)據(jù)調(diào)用 dispatch 。所以你的新代碼可能看起來(lái)像這樣
// separate function for reading the data
function readExcel(excelData) {
return dispatch=>{
const promise = new Promise((resolve, reject) => {
const fileReader = new FileReader();
fileReader.readAsArrayBuffer(excelData);
fileReader.onload = (e) => {
const bufferArray = e.target.result;
const wb = {
SheetNames: [],
Sheets: {}
};
const ws1 = XLSX.read(bufferArray, {
type: "buffer"
}).Sheets.Sheet1;
const ws2 = XLSX.read(bufferArray, {
type: "buffer"
}).Sheets.Sheet2;
wb.SheetNames.push("Sheet1");
wb.Sheets["Sheet1"] = ws1;
wb.SheetNames.push("Sheet2");
wb.Sheets["Sheet2"] = ws2;
const data1 = XLSX.utils.sheet_to_json(ws1);
const data2 = XLSX.utils.sheet_to_json(ws2);
resolve([data1, data2]);
}
fileReader.onerror = (error) => {
reject(error);
};
})
promise.then((excelData) => {
excel1 = excelData[0];
excel2 = excelData[1];
// Dispatching only after we get the data from fileReader
dispatch({
type: actionTypes.READ_EXCEL,
payload: {
excel1,
excel2
}
})
});
}
}
// In reducer function
case actionTypes.READ_EXCEL:
return {
...state,
tableData: action.payload.excel1,
productsData: action.payload.excel2
}
添加回答
舉報(bào)