如何循环遍历 json 数组项并使用某些 json 对象发出异步 API 请求 [英] How do I loop through an array item of json and make async API requests with certain json objects
问题描述
如果我的问题看起来有点新手,我很抱歉,我对异步编程很陌生,我仍在努力解决所有问题.我还试图弄清楚如何在这里提出好的问题,因此我尝试包含正确的信息和可重复的示例.谢谢
I apologize if my question seems kind of newbie, I'm very new to async programming and I'm still trying to figure everything out. I'm also trying to figure out how to ask good questions here so i tried to include the right information and a reproducable example. Thank you
我正在建立一个简单的在线商店,其中只有四种产品.
I have a simple online store i'm building that only has four products.
当我的服务器端客户端通过 JSON 接收用户购物车内容时,它接收 product_id、quantity 和 price_id 作为 JSON 数据数组
When my server side client receives the users cart contents via JSON It receive the product_id, quantity, and price_id as an array of JSON data
我正在尝试将其配置为
遍历每个数组项,
loop through each array item,
获取product_id和price_id,将它们发送到 Stripe API 以分别接收产品对象和价格对象,
grab the product_id and price_id, send them to the stripe API to recieve the product object and price object respectively,
分配unit_amount"来自价格对象和图像"的值值和名称"从产品对象到它们自己的变量的值
assign the "unit_amount" value from the price object and the "images" value and "name" value from the products object to their own variable
将软管变量放入一个数组中,并将该数组推送到 lineItems 数组,该数组将用作对 Stripe Checkout 的创建会话请求的变量
Put hose variables into an array and push the array to the lineItems array, which is to be used as a variable for the create-session request to Stripe Checkout
简而言之:
预期行为:从数组中的每个项目生成 price_data 对象,数组与 line_items 对象一起发送到会话请求以进行条带结帐,然后用户被重定向到结帐页面,结帐中包含 price_data 项目.
Expected behavior: price_data object produced from each item in the array, array is sent with line_items object to session request to stripe checkout then user is redirected to checkout page with price_data items in checkout.
当前行为:从 Stripe api 检索到的价格数据无法分配给变量或传递给 price_data.返回类型错误:无法读取未定义的属性unit_amount".
current behavior: price data retrieved from Stripe api unable to be assigned to variable or passed to price_data. Returning TypeError: Cannot read property 'unit_amount' of undefined.
const stripe = require('stripe')('sk_test_51Hemg7ETi3TpMq6bUmiw1HoxERPmReLOT3YLthf11MEVh4xCmnsmxtFHZRlWpimoSnwHjmUOKNkOFsbr9lEEIybe00SQF71RtF');
//This is a test secret key for a dummy stripe account, don't worry I'm not sharing anything sensitive
const express = require('express');
const app = express();
app.use(express.static('.'));
const YOUR_DOMAIN = 'http://localhost:4242';
app.post('/create-session', async(req, res) => {
//Body of the POST request
const cartContents = [{
product_id: 'prod_IHb8dX3ESy2kwk',
quantity: '2',
price_id: 'price_1Hh1wcETi3TpMq6bSjVCf3EI'
},
{
product_id: 'prod_IFIIyTO0fHCfGx',
quantity: '2',
price_id: 'price_1HeniJETi3TpMq6bPDWb3lrp'
}
]
//Array to push parsed data onto for line_items object in stripe session
var lineItems = [];
cartContents.forEach(async(item, index, array) => {
//Retrieve price object from stripe API:
const price = await stripe.prices.retrieve(
item.price_id
).then(
function(message) {
console.log(message.unit_amount);
//log the unit_amount value from price object
},
function(error) {
console.log("Reject:", error);
}
);
//retrieve product object from stripe API
const product = await stripe.products.retrieve(
item.product_id
).catch(err => console.error('error also'));
console.log(product.name)
// retrieve "name" and "images" from returned product object and assign to variable
const productName = product.name;
const productImage = product.images;
//retrieve "unit_amount" from returned price object and assign to variable
const productPrice = price.unit_amount
//retrieve item quantity from cartContents object and assign to variable
const productQuantity = item.quantity
//Add variables to item and push to lineItems array
lineItems.push({
price_data: {
currency: 'usd',
product_data: {
name: productName,
images: [productImage],
},
unit_amount: productPrice,
},
quantity: productQuantity,
})
});
const session = await stripe.checkout.sessions.create({
payment_method_types: ['card'],
line_items: lineItems,
mode: 'payment',
success_url: `http://localhost:5001/success.html`,
cancel_url: `http://localhost:5001/cancel.html`,
});
res.json({
id: session.id
});
谢谢
推荐答案
你的主要问题是 .forEach(async
很少,如果有的话,会像你期望的那样工作
Your main issue is that .forEach(async
is very rarely, if at all, going to work like you expect
然而,另一个问题是
const price = await stripe.prices.retrieve(item.price_id)
.then(function(message) {
console.log(message.unit_amount);
//log the unit_amount value from price object
},
function(error) {
console.log("Reject:", error);
}
);
这将导致 price
成为 undefined
- 因为 .then
不返回任何内容
This will result in price
being undefined
- since the .then
doesn't return anything
将 .then
/.catch
与 async
/await
混合总是(通常)不是一个好主意>
It's always (usually) not a good idea to mix .then
/.catch
with async
/await
所以 - 解决这两个问题 - 你的代码变成了
So - fixing those two issues - your code becomes
const stripe = require('stripe')('sk_test_51Hemg7ETi3TpMq6bUmiw1HoxERPmReLOT3YLthf11MEVh4xCmnsmxtFHZRlWpimoSnwHjmUOKNkOFsbr9lEEIybe00SQF71RtF');
//This is a test secret key for a dummy stripe account, don't worry I'm not sharing anything sensitive
const express = require('express');
const app = express();
app.use(express.static('.'));
const YOUR_DOMAIN = 'http://localhost:4242';
app.post('/create-session', async(req, res) => {
//Body of the POST request
const cartContents = [{
product_id: 'prod_IHb8dX3ESy2kwk',
quantity: '2',
price_id: 'price_1Hh1wcETi3TpMq6bSjVCf3EI'
}, {
product_id: 'prod_IFIIyTO0fHCfGx',
quantity: '2',
price_id: 'price_1HeniJETi3TpMq6bPDWb3lrp'
}
];
//Array to push parsed data onto for line_items object in stripe session
const lineItems = [];
try {
for (let item of cartContents) {
//Retrieve price object from stripe API:
const price = await stripe.prices.retrieve(item.price_id);
console.log(price.unit_amount);
//log the unit_amount value from price object
//retrieve product object from stripe API
const product = await stripe.products.retrieve(item.product_id);
console.log(product.name);
// retrieve "name" and "images" from returned product object and assign to variable
const productName = product.name;
const productImage = product.images;
//retrieve "unit_amount" from returned price object and assign to variable
const productPrice = price.unit_amount;
//retrieve item quantity from cartContents object and assign to variable
const productQuantity = item.quantity;
//Add variables to item and push to lineItems array
lineItems.push({
price_data: {
currency: 'usd',
product_data: {
name: productName,
images: [productImage],
},
unit_amount: productPrice,
},
quantity: productQuantity,
});
}
const session = await stripe.checkout.sessions.create({
payment_method_types: ['card'],
line_items: lineItems,
mode: 'payment',
success_url: `http://localhost:5001/success.html`,
cancel_url: `http://localhost:5001/cancel.html`,
});
res.json({id: session.id});
} catch(e) {
// handle error here
}
});
这篇关于如何循环遍历 json 数组项并使用某些 json 对象发出异步 API 请求的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!