Это преобразователь GraphQL. Проблема заключается в обработке промисов с помощью async/await.
Я пытался реализовать обработку промисов, но не могу настроить правильно, у меня нет большого опыта в обработке промисов, некоторые учебные материалы очень помогут.
Насколько я понимаю, сценарий остановится там, где вызывается ожидание, и продолжится после завершения вызова ожидания. но это в обход ожидания. вызов await завершается после возврата значения
allDocs: async (args, context) => context().then(async client => {
let db = client.db(dbName)
const id = args.identifier.trim()
let nameArr = []
return await db.collection("collection").find({
$or: [{
"a.iden": id
}, {
"b.iden": id
}]
}).toArray().then(async (arr) => {
let year
arr.map(async element => {
let pmcid = element.pmc_id.toUpperCase()
try {
year = await db.collection("Another_collection").findOne({"pmcid" : query})["year"]
} catch (e) {
year = null
}
element["publication_year"] = year
})
return await arr
}).then((arr)=>{
client.close()
return {
"documents": arr,
"count": arr.length,
"searchkey": id
}
})
}),
Ожидаемое возвращаемое значение должно иметь «publication_year» как некоторый год, сейчас оно дает null.
Спасибо за помощь



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Кажется, вы смешиваете Promises с асинхронно/ожидание, и это немного сложно понять. Всегда лучше разбить свой код, изменив биты Promise на использование асинхронно/ожидание, так как это поможет вам сузить проблему. Вы также можете обернуть весь блок в Попробуйте поймать, что упрощает обработку как синхронных, так и асинхронных ошибок.
Итак, для начала вы можете изменить вызов функции контекста, который возвращает обещание использовать асинхронное ожидание как
allDocs: async (args, context) => {
try {
const client = await context()
....
} catch(err) {
}
}
Затем сделайте то же самое с вызовом функции toArray(), который возвращает обещание, которое можно разрешить с помощью асинхронно/ожидание:
allDocs: async (args, context) => {
try {
const client = await context()
const db = client.db(dbName)
const id = args.identifier.trim()
const results = await db.collection('collection').find({
'$or': [
{ 'a.iden': id },
{ 'b.iden': id }
]
}).toArray()
const arr = results.map(async doc => {
const pmcid = doc.pmc_id.toUpperCase()
const { year } = await db.collection('Another_collection')
.findOne({'pmcid' : pmcid })
return {
...doc,
publication_year: year
}
})
client.close()
return {
'documents': arr,
'count': arr.length,
'searchkey': id
}
} catch(err) {
// handle error
}
}
Вызов другой коллекции для получения publication_year может быть выполнен с использованием конвейера $lookup в одном вызове, а не в цикле карты. Рассмотрим следующий конвейер
allDocs: async (args, context) => {
try {
const client = await context()
const db = client.db(dbName)
const id = args.identifier.trim()
const pipeline = [
{ '$match': {
'$or': [
{ 'a.iden': id },
{ 'b.iden': id }
]
} },
{ '$lookup': {
'from': 'Another_collection',
'let': { 'pmcId': '$pmc_id' },
'pipeline': [
{ '$match': {
'$expr': {
'$eq': [
'$pmcid',
{ '$toUpper': '$$pmcId' }
]
}
} }
],
'as': 'pmc'
} },
{ '$addFields': {
'publication_year': {
'$arrayElemAt': [ '$pmc.year', 0 ]
}
} },
{ '$project': { 'pmc': 0 } }
]
const arr = await db.collection('collection').aggregate(pipeline).toArray()
client.close()
return {
'documents': arr,
'count': arr.length,
'searchkey': id
}
} catch(err) {
// handle error
}
}
Спасибо, было здорово познакомиться с подходом к агрегации, он упростил задачу и открыл новые возможности.