Обещание разрешает каждое условие «если» вместо возврата только одного

#node.js #promise #async-await

#node.js #обещание #асинхронное ожидание

Вопрос:

Я пытаюсь вернуть конкретный ответ, в зависимости от некоторых данных, которые я получаю. Проблема в том, что каждый раз в конечном итоге возвращается последний ответ, даже если он прошел через правильные условия :

 api.get('/database-manager/request-status', async (lambdaRequest, lambdaResponse, next) => {
        if (connectionPool == null) {
            connectionPool = await mySQLConnectionPool();
        }
        requestId = lambdaRequest.headers["request-id"]
        const res = await new Promise(
            async function (resolve, reject) {
                await getRequests()
                for (let index in requestIds) {
                    console.log(`requestId in header : ${requestId}`)
                    if (requestId == requestIds[index].request_id) {
                        console.log(`id in list : ${requestIds[index].request_id}`)
                        requestStatus = requestIds[index].request_status
                        console.log("am in the first if ")
                        if (requestStatus == 'Finished') {
                            console.log("am in the finished if ")
                            ec2InstanceLink = requestIds[index].instance_link
                            let response = {
                                "statusCode": 200,
                                "headers": {},
                                "isBase64Encoded": false,
                                "body": ec2InstanceLink
                            }
                            resolve(response)
                        } else {
                            console.log("am in the not finished if ")
                            let response = {
                                "statusCode": 200,
                                "headers": {},
                                "isBase64Encoded": false,
                                "body": JSON.stringify({status: requestStatus})
                            }
                            resolve(response)
                        }
                    }
                    console.log("cannot find")
                    let response = {
                        "statusCode": 200,
                        "headers": {},
                        "isBase64Encoded": false,
                        "body": "Request-Id doesn't exist"
                    }
                    resolve(response)
                }
            }
        )
        return res;
    }
)
  

И это журнал консоли, доказывающий, что, хотя он был в правильной ситуации, он не вернул правильный ответ. :

 1600950719600   START RequestId: 3436e868-b36f-4d51-88c0-0c6b3d06bbb7 Version: $LATEST
1600950721777   2020-09-24T12:32:01.777Z    3436e868-b36f-4d51-88c0-0c6b3d06bbb7    INFO    requestId in header : 911e8b872dbe7fc8a2821008bf8af87c
1600950721795   2020-09-24T12:32:01.777Z    3436e868-b36f-4d51-88c0-0c6b3d06bbb7    INFO    cannot find
1600950721815   2020-09-24T12:32:01.815Z    3436e868-b36f-4d51-88c0-0c6b3d06bbb7    INFO    requestId in header : 911e8b872dbe7fc8a2821008bf8af87c
1600950721815   2020-09-24T12:32:01.815Z    3436e868-b36f-4d51-88c0-0c6b3d06bbb7    INFO    id in list : 911e8b872dbe7fc8a2821008bf8af87c
1600950721815   2020-09-24T12:32:01.815Z    3436e868-b36f-4d51-88c0-0c6b3d06bbb7    INFO    am in the first if
1600950721815   2020-09-24T12:32:01.815Z    3436e868-b36f-4d51-88c0-0c6b3d06bbb7    INFO    am in the not finished if
1600950721815   2020-09-24T12:32:01.815Z    3436e868-b36f-4d51-88c0-0c6b3d06bbb7    INFO    cannot find
1600950721815   2020-09-24T12:32:01.815Z    3436e868-b36f-4d51-88c0-0c6b3d06bbb7    INFO    requestId in header : 911e8b872dbe7fc8a2821008bf8af87c
1600950721815   2020-09-24T12:32:01.815Z    3436e868-b36f-4d51-88c0-0c6b3d06bbb7    INFO    cannot find
1600950721836   END RequestId: 3436e868-b36f-4d51-88c0-0c6b3d06bbb7
1600950721836   REPORT RequestId: 3436e868-b36f-4d51-88c0-0c6b3d06bbb7  Duration: 2235.83 ms    Billed Duration: 2300 ms    Memory Size: 128 MB Max Memory Used: 94 MB  Init Duration: 529.96 ms
  

Комментарии:

1. Почему new Promise конструкция? Где requestIds определено?

2. ну, я просто сохраняю обещание в переменной на данный момент, я мог бы использовать его позже.

3. Что произойдет, если вы добавите a return; после resolve операторов?

4. К сожалению, @Christian по-прежнему не работает.

5. Посмотрите, можете ли вы использовать Object.values() и Array.prototype.find() . В сочетании они позволят вам значительно упростить код.

Ответ №1:

Проблема в том, что вы вызываете resolve несколько раз, но эффективен только первый.

Структура упрощена:

 await new Promise(
            async function (resolve, reject) {
                for (...) {
                    if (...) {
                        if (...) {
                            resolve(response)
                        } else {
                            resolve(response)
                        }
                    }
                    resolve(response)
                }
            }
        )
  

resolve Вызывается на каждой итерации цикла for, и обещания могут быть разрешены только один раз. Поскольку код является синхронным, он будет обрабатывать все идентификаторы запросов, но результатом await new Promise будет первый ответ, который он Request-Id doesn't exist .

Вот почему вы видите неправильный ответ. Чтобы исправить это, вам нужно разрешить обещание только один раз. Как это сделать, зависит от того, чего вы хотите достичь, если вы ищете соответствующий responseId, это может быть так же просто, как переместить последний resolve из цикла for.