gpt4 book ai didi

javascript - 异步/等待和 promise

转载 作者:太空宇宙 更新时间:2023-11-04 03:21:42 26 4
gpt4 key购买 nike

我在使用 Node v8.1 时使用 async/await 时遇到问题。看来我的问题是我没有从异步函数返回 promise 。这导致程序流程无序运行。我想通过制作一个函数 async该函数会自动返回一个 promise ,但我遇到的情况并非如此。

我希望下面的程序输出:

Validating xlsx file...

(text from validateParsedXlsx)

Adding users to cognito...

(text from addUsersToCognito)

Adding users to dynamodb...

(text from addUsersToDynamodb)

相反,我得到:

Validating xlsx file...

Adding users to cognito...

Adding users to dynamodb...

(text from validateParsedXlsx)

(text from addUsersToCognito)

(text from addUsersToDynamodb)

这个问题似乎非常明显,validateParsedXlsx() addUsersToCognito()addUsersToDynamodb()没有返回 promise 。再次,我认为通过使用 async关键字,该函数会自动处理这个问题。

感谢您的帮助。

这是我的脚本:

const xlsx = require('xlsx');
const AWS = require('aws-sdk');

AWS.config.update({region: 'us-west-2'});
const documentClient = new AWS.DynamoDB.DocumentClient({convertEmptyValues: true});

async function main(){

if (!process.argv[2]) {
console.log('\nAbsolute filepath missing. Pass the absolute filepath in as command line argument.\n')
process.exit(1);
}

const xlsxFilePath = process.argv[2];
let parsedXlsx = [];
try {
parsedXlsx = parseXlsx(xlsxFilePath);
} catch (error) {
if(error.code === 'ENOENT') {
console.log(`\nThe file path: ${process.argv[2]} cannot be resolved\n`)
} else {
console.log(error);
}
}

console.log('\n\nValidating xlsx file...\n');
await validateParsedXlsx(parsedXlsx);
console.log('\n\nAdding users to cognito...\n');
await addUsersToCognito(parsedXlsx);
console.log('\n\nAdding users to dynamodb...\n');
await addUsersToDynamodb(parsedXlsx);

}

function parseXlsx(filePath) {

const workbook = xlsx.readFile(filePath);
const sheetNameList = workbook.SheetNames;

const parsedXlsxSheets = sheetNameList.map(function (y) {
const worksheet = workbook.Sheets[y];
const headers = {};
const data = [];

for (z in worksheet) {
if(z[0] === '!') continue;
//parse out the column, row, and value
const col = z.substring(0,1);
const row = parseInt(z.substring(1));
const value = worksheet[z].v;

//store header names
if(row == 1) {
headers[col] = value;
continue;
}

if(!data[row]) data[row] = {};
data[row][headers[col]] = value;
}
//drop those first two rows which are empty
data.shift();
data.shift();
return data;
});

return parsedXlsxSheets[0]
}

async function validateParsedXlsx(users) {

let error = false;
users.forEach(async (user, index) => {
if (!user.email) {
console.log(`User at row ${index + 2} doesn't have 'email' entry in xlsx file.`);
error = true;
}
if (!user.displayName) {
console.log(`User at row ${index + 2} doesn't have 'displayName' entry in xlsx file.`);
error = true;
}
if (!user.serviceProviderId) {
console.log(`Userat row ${index + 2} doesn't have 'displayName' entry in xlsx file.`);
error = true;
} else {
const params = {
TableName: 'service-providers',
Key: {
serviceProviderId: user.serviceProviderId
}
}

const response = await documentClient.get(params).promise();
if (!response.Item) {
console.log(`User at row ${index +2} does not have a valid serviceProviderId.`);
error = true;
} else {
console.log(`User ${user.email} is valid, assigned to service provider: ${response.Item.displayName}`);
}
}

if (error) {
console.log(`Every user in xlsx file must have these attributes, spelled correctly: email, displayName, and serviceProviderId\n\nIn addition, make sure the serviceProviderId is correct by checking the service-providers dynanomdb table.`);
process.exit(1);
}
});

}

async function addUsersToCognito(users) {

const cognitoIdentityServiceProvider = new AWS.CognitoIdentityServiceProvider();

const results = await cognitoIdentityServiceProvider.listUserPools({MaxResults: 10}).promise();

let serviceProviderUserPoolId = '';

results.UserPools.forEach((userPool) => {
if(userPool.Name === 'service-provider-users') {
serviceProviderUserPoolId = userPool.Id;
}
});

users.forEach(async (user) => {

const params = {
UserPoolId: serviceProviderUserPoolId,
Username: user.email,
DesiredDeliveryMediums: ['EMAIL'],
TemporaryPassword: 'New_User1',
UserAttributes: [
{
Name: 'email',
Value: user.email
},
{
Name: 'custom:service_provider_id',
Value: user.serviceProviderId
}
]
}

try {
await cognitoIdentityServiceProvider.adminCreateUser(params).promise();
console.log(`Added user ${user.email} to cognito user pool`);
} catch (error) {
if (error.code === 'UsernameExistsException') {
console.log(`Username: ${user.email} already exists. No action taken.`);
}
else {
console.log(error);
}
}
});

}

async function addUsersToDynamodb(users) {

users.forEach(async (user) => {
const params = {
TableName: 'service-provider-users',
Item: {
serviceProviderId: user.serviceProviderId,
userId: user.email,
displayName: user.displayName,
isActive: false,
role: 'BASIC'
},
ConditionExpression: 'attribute_not_exists(userId)'
}

try {
await documentClient.put(params).promise();
console.log(`Added user ${user.email} to dynamodb user table`);
} catch (error) {
if (error.code === 'ConditionalCheckFailedException') {
console.log(`User ${user.email} already in the dynamodb table service-provider-users`);
} else {
console.log(error);
}
}
});

}

main();

最佳答案

  users.forEach(async (user, index) => {

这开始了一些有希望的行动,但永远不会等待它们。可以做:

  await Promise.all(users.map(async (user, index) => {

...并行执行它们或执行以下操作:

  await users.reduce((chain, user, index) => async (user, index) => {
await chain;
//...
}, Promise.resolve());

依次执行它们。

<小时/>

PS:使用process.exit应该是结束程序的最后一个选项

关于javascript - 异步/等待和 promise ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49454638/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com