Nodejs异步函数没有按顺序运行



我试图将POST请求发送到我的后端,这个POST请求需要multipart/form-data,所以在我将其全部作为POST请求发送之前,我将图像位置转换为Buffers,但由于Nodejsasync行为,我不知道如何使功能按顺序运行。我应该如何重新安排/重写这段代码?

import axios from "axios";
import { readFileSync, readFile as rf, PathOrFileDescriptor } from "fs";
import FormData from "form-data";
import dotenv from "dotenv";
dotenv.config();
// readfile promise
const readFile = (file: PathOrFileDescriptor) => {
return new Promise((resolve, reject) => {
rf(file, (err, data) => {
if (err) reject(err.message);
resolve(data);
});
});
};
console.log("Parsing JSON data 💾");
const jsonData = readFileSync("data/data.json").toString();
const products: any[] = JSON.parse(jsonData).products;
console.log("Products Store in JavaScript Object 🛒");
products.forEach((product: any, index: number) => {
console.log(
`Creating Product ${index + 1}/${products.length} - ${product.name}`
);
let requestData = new FormData();
for (const [key, value] of Object.entries<string>(product)) {
if (key.includes("image")) {
console.log(`Converting ${key} in Image Blob 🖼`);
readFile(value)
.then((data) => {
requestData.append(key, data);
console.log(`${key} Converted ✔`);
})
.catch((err) => {
console.log(`${key} Failed to Convert ❌ - Error=${err}`);
});
} else {
if (key === "variants") {
requestData.append(key, JSON.stringify(value));
} else {
requestData.append(key, value);
}
}
}
axios
.post("http://localhost:8000/api/v1/product/create", requestData, {
headers: {
"Content-Type": "multipart/form-data",
Cookie: `access_token=${process.env.ACCESS_TOKEN}; csrftoken=${process.env.CSRF_TOKEN}`,
},
withCredentials: true,
})
.then(() => {
console.log(`Product - ${product.name} Created ✔`);
})
.catch((err) => {
console.log(`Product - ${product.name} Failed to create ❌`);
if (err.response) {
console.log(err.response.data);
} else {
console.log("Internal server error");
}
});
});

我正在解析的数据是一个类似于

的对象数组
{
"store": "maki-2",
"name": "Nike Sportwear Down-fill Windrunner Jacket",
"description": "The Nike Sportswear Jacket warms up your winter wardrobe with a serious supply of down. This lightweight zip-up style features water-resistant and windproof Nike Shield technology to help keep you comfortable in rough weather. A subtle chevron design, which references the OG Windrunner, graces the chest.",
"brand": "Nike",
"gender": "U",
"category": "outwear",
"image_v0_1": "data/images/outwear/Nike Sportswear Down-Fill Windrunner/sportswear-down-fill-windrunner-jacket-hHNjxL (3).png",
"image_v0_2": "data/images/outwear/Nike Sportswear Down-Fill Windrunner/sportswear-down-fill-windrunner-jacket-hHNjxL.jpg",
"image_v0_3": "data/images/outwear/Nike Sportswear Down-Fill Windrunner/sportswear-down-fill-windrunner-jacket-hHNjxL.png",
"image_v1_1": "data/images/outwear/Nike Sportswear Down-Fill Windrunner/sportswear-down-fill-windrunner-jacket-hHNjxL (1).jpg",
"image_v1_2": "data/images/outwear/Nike Sportswear Down-Fill Windrunner/sportswear-down-fill-windrunner-jacket-hHNjxL (1).png",
"image_v1_3": "data/images/outwear/Nike Sportswear Down-Fill Windrunner/sportswear-down-fill-windrunner-jacket-hHNjxL (2).png",
"variants": [
{
"is_default": false,
"price": 23000,
"quantity": 23,
"size": "M",
"color": "multi-colored"
},
{
"is_default": true,
"price": 25000,
"quantity": 23,
"size": "L",
"color": "black"
}
]
},

您可以使用Promise.all来等待map函数中所有的promise完成:

import axios from "axios";
import {
readFileSync,
readFile as rf,
PathOrFileDescriptor
} from "fs";
import FormData from "form-data";
import dotenv from "dotenv";
dotenv.config();
// readfile promise
const readFile = (file: PathOrFileDescriptor) => {
return new Promise((resolve, reject) => {
rf(file, (err, data) => {
if (err) reject(err.message);
resolve(data);
});
});
};
console.log("Parsing JSON data 💾");
const jsonData = readFileSync("data/data.json").toString();
const products: any[] = JSON.parse(jsonData).products;
console.log("Products Store in JavaScript Object 🛒");

await Promise.all(
products.map(async(product: any, index: number) => {
console.log(
`Creating Product ${index + 1}/${products.length} - ${product.name}`
);
let requestData = new FormData()
Object.keys(product).map(async(key: any) => {
if (key.includes("image")) {
try {
const data = await readFile(product[key])
requestData.append(key, data)
console.log(`${key} Converted ✔`);
} catch (e) {
console.log(`${key} Failed to Convert ❌ - Error=${e}`);
}
} else {
if (key === "variants") {
requestData.append(key, JSON.stringify(value));
} else {
requestData.append(key, value);
}
}
return key;
});
await axios
.post("http://localhost:8000/api/v1/product/create", requestData, {
headers: {
"Content-Type": "multipart/form-data",
Cookie: `access_token=${process.env.ACCESS_TOKEN}; csrftoken=${process.env.CSRF_TOKEN}`,
},
withCredentials: true,
})
.then(() => {
console.log(`Product - ${product.name} Created ✔`);
})
.catch((err) => {
console.log(`Product - ${product.name} Failed to create ❌`);
if (err.response) {
console.log(err.response.data);
} else {
console.log("Internal server error");
}
});
return product;
})
);

你应该在for循环中链接承诺。

var readFilePromise = Promise.resolve();
for (const [key, value] of Object.entries < string > product) {
if (key.includes("image")) {
console.log(`Converting ${key} in Image Blob 🖼`);
readFilePromise = readFilePromise
.then(() => readFile(value))
.then((data) => {
requestData.append(key, data);
console.log(`${key} Converted ✔`);
})
.catch((err) => {
console.log(`${key} Failed to Convert ❌ - Error=${err}`);
});
} else {
if (key === "variants") {
requestData.append(key, JSON.stringify(value));
} else {
requestData.append(key, value);
}
}
}

和你的POST请求应该只在承诺被解决后进行。

readFilePromise.then(() => {
axios.post(...)
})

最新更新