问题
I am re-writing my website and am trying to import my members from array of JSON objects.
Each object represents a band that the user has uploaded. So I wrote a quick file that works with the list and my new database / authentication system, auth0.
As outline in the comments below... First I Request an access token so I can create an account for each member using Auth0. Then I iterate through my array of objects representing bands. For each band object I have the code do a few things... First, it creates a new account on my auth system. This sends back a user ID. I add the user ID to the band object to be stored in my database. It adds the location as well as adds a few posts that the user may have had from the old system.
This all works well if I do one user... But if I let it iterate through the whole array it doesn't work. It added about 15 bands to the auth system and 50 bands to the database... It seems like its going too fast to successfully publish them all. Any ideas on how to fix this?
** Also tried this with a for loop instead of for each. Moving everything inside the for loop creates both the same number of bands and user accounts, but now it times out at about 10 bands instead of doing all of them.
Thanks!
const uuidv4 = require('uuid')
const BulkBands = require('./BulkBands')
const fetch = require("node-fetch");
let bandCount = 0
//First I need to get an Access Token for my Auth Proider, Auth0
const getAccessToken = async () => {
try {
let response = await fetch(`https://nm-music.auth0.com/oauth/token`, {
method: 'POST',
headers: { 'content-type': 'application/json' },
body: '{"client_id":"xxxxxxxxx","client_secret":"xxxxxxxxx", "audience":"https://xxxxxxxx.com/api/v2/","grant_type":"client_credentials"}'
})
const responseData = await response.json()
//Now I start The Process of Adding the Bands.
addTheBands(responseData.access_token)
} catch (error) {
console.log(error)
}
}
//Here I use the array method, forEach() to iterate over the list of about 77 bands.
const addTheBands = (accessToken) => {
BulkBands.forEach(band => {
//The first thing I want to do for each band is create an account for them on the Auth system.
createNewAccount(band, accessToken)
})
}
//Here is the function to create the account.
const createNewAccount = async (band, accessToken) => {
try {
const response = await fetch(`https://xxxxxxxxx.com/api/v2/users`, {
method: 'POST',
headers: {
'content-type': 'application/json;',
"Authorization": `Bearer ${accessToken}`,
},
body: JSON.stringify({
"connection": 'Username-Password-Authentication',
"email": band.bandEmail,
// "phone_number": "+19995550123",
"user_metadata": {},
"blocked": false,
"email_verified": false,
// "phone_verified": false,
"app_metadata": {},
// "given_name": band.bandName,
// "family_name": band.bandName,
"name": band.bandEmail,
// "nickname": "Johnny",
// "picture": "https://secure.gravatar.com/avatar/15626c5e0c749cb912f9d1ad48dba440?s=480&r=pg&d=https%3A%2F%2Fssl.gstatic.com%2Fs2%2Fprofiles%2Fimages%2Fsilhouette80.png",
// "user_id": "",
// "connection": "Initial-Connection",
"password": "xxxxxxxx",
"verify_email": false,
// "username": band.bandEmail
})
})
let newUserResponse = await response.json()
//Now that their account has been made, I want to add the band to my database, and use the Account ID from newUserResponse as the userId for the band. That way the band is associted with their account.
addTheBand({
quoteGenerator: [],
userId: newUserResponse.identities[0].user_id,
posts: [
{
"type": "band",
"data": "",
"date": new Date(),
"postId": uuidv4(),
"approved": null,
"rockOn": []
},
],
type: 'band',
bandName: band.bandName,
bandEmail: band.bandEmail,
bandGenre: band.bandGenre,
bandBio: band.bandBio,
youtube: [band.youtube1, band.youtube2],
published: false,
cancellationPolicy: 'You may cancel this performance up to 2 weeks prior to the performance date without penalty. If this performance is cancelled within 2 weeks of the performance date the booking party will be required to pay 50% of the booking fee to the band. If the booking is cancelled within 3 days of the performance date the full payment is required to be paid to the band. ',
baseCost: band.baseCost,
mainDate: {
charge: 0,
sunday: 0,
monday: 0,
tuesday: 0,
wednesday: 0,
thursday: 0,
friday: 0,
saturday: 0,
}
}, band)
} catch (error) {
console.log(error)
}
}
//Now to start adding the band...
const addTheBand = async (newBand, band) => {
let newLocation = []
let accessToken = ''
//I need to geo-locate each band for my new system. So I use the google api to do so.
try {
let resposne = await fetch(`https://maps.googleapis.com/maps/api/geocode/json?address=${band.bandLocation}&key=xxxxxxxxx`)
const responseLocation = await resposne.json()
newLocation = [responseLocation.results[0].geometry.location.lng, responseLocation.results[0].geometry.location.lat ]
// I store the geo location for the band and now I post the new band to my database. The Geo Location is Indexed and does not work if I post it - I need to do this after the band is posted - no clue why.
response = await fetch('http://localhost:5000/api/autoquotegenerators', {
method: 'POST',
headers: {
"Content-Type": 'application/json; charset=UTF-8'
},
body: JSON.stringify(newBand)
})
const responseData = await response.json()
if(responseData){
console.log('Band Added');
//Like I said before... I need to add the geo-location now. So this function will do so.
updateBandLocation({
geometry: {
coordinates: newLocation,
city: band.bandLocation,
}
}, responseData._id, responseData, band)
}
} catch (error) {
console.log(error)
}
}
//I send the geo-location data to this function... it also takes care of a few last minute things such as posts, and quote figures and such. It all works.
const updateBandLocation = async (newLocation, bandUserId, band, oldBand) => {
console.log('adding location...')
let newPosts = [...band.posts]
let newQuoteGenerator = []
if(oldBand.timedRate > 0 ){
newQuoteGenerator.push({
cardType: "timed",
inputType: "select",
cardTitle: "Hourly Rate",
charge: oldBand.timedRate,
price: 0,
cardId: uuidv4()
})
}
if(oldBand.youtube1){
newPosts.push({
type: "video",
data: oldBand.youtube1,
date: new Date(),
postId: uuidv4(),
rockOn: []
})
}
if(oldBand.youtube2){
newPosts.push({
type: "video",
data: oldBand.youtube2,
date: new Date(),
postId: uuidv4(),
rockOn: []
})
}
try {
const response = await fetch(`http://localhost:5000/api/autoquotegenerators/${bandUserId}`, {
method: 'PUT',
headers: {
"Content-Type": "application/json; charset=UTF-8",
},
body: JSON.stringify({
quoteGenerator: newQuoteGenerator,
bandLocation: newLocation,
posts: newPosts
})
})
const responseData = await response.json()
bandCount += 1
console.log(bandCount)
} catch (error) {
console.log(error)
}
}
getAccessToken()
来源:https://stackoverflow.com/questions/62314291/foreach-iterates-too-fast-with-async-await-skipping-data