在 node js 中使用 promise 时函数工作不正确 [英] Function work incorrectly when using promise in node js

查看:29
本文介绍了在 node js 中使用 promise 时函数工作不正确的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这样的路线:

router.get('/:projectid/, (req, res) => {
    testCase.getTestCaseDetail(req.params.projectid, req.params.testcaseid, req.params.snapshotId).then(testcaseData => {
      res.render('testCaseService', {
        title: 'Page',
        testcase: testcaseData,
        layout: 'project_layout',
      });
    });
  });

在处理函数中,我有 getTestCaseDetail 函数:

In the handler function, I have getTestCaseDetail function:

function getTestCaseDetail(projectId, id, snapshotId) {
  let testCaseId = parseInt(id);
  return new Promise(((resolve, reject) => {
    return testCaseSchema.aggregate([
      { $match: { 'projectId': projectId, 'testCaseId': testCaseId } },
      {
        $lookup: {
          from: snapshotInfoSchema.collection.collectionName,
          localField: testCaseObj.SERVICE_ID,
          foreignField: 'artifacts.id',
          as: 'services',
        },
      },
      { $unwind: '$services' },
      {
        $match: {
          'services.snapshot.id': snapshotId,
        }
      }
    ]).then(testCaseResult => {
      resolve(addTestCasesV2(testCaseResult, snapshotId));
    })
      .catch(err => {
        reject(err);
      })
  }));
}

addTestCasesV2函数

const addTestCasesV2 = function (testcases, snapshotId) {
  const result = [];
  let serviceTypeMapping;
  let serviceName;
  let testCase = {
    id: '',
    testCaseId: '',
    name: '',
    serviceName: '',
    serviceType: '',
    modifiedAt: '',
    testScripts: '',
    snapshotId: '',
    services: '',
    inputs: [],
    outputs: [],
  };
  let promiseInputResults, promiseOutputResults;
  const testcasesList = lodash.map(testcases, (tc) => {
    const artifacts = lodash.map(tc.services.artifacts, (art) => {
      if (art.id === tc.service_id) {
        serviceTypeMapping = art.processType.serviceTypeName;
        serviceName = art.name;
        if (!commonUtil.isUndefined(art.processParameters)) {
          if (!commonUtil.isUndefined(art.processParameters.input)) {
            promiseInputResults = lodash.map(art.processParameters.input, (ip) => {
              let classId = commonUtil.getArtifactId(ip.classId);
              return objectType.getObjectTypeByClassId(snapshotId, classId)
            });
          }

          if (!commonUtil.isUndefined(art.processParameters.output)) {
            promiseOutputResults = lodash.map(art.processParameters.output, (ip) => {
              let classId = commonUtil.getArtifactId(ip.classId);
              return objectType.getObjectTypeByClassId(snapshotId, classId)
            });
          }
        }
        testCase.id = tc.testCaseId;
        testCase.testCaseId = tc.testCaseId;
        testCase.name = tc.name;
        testCase.serviceName = serviceName;
        testCase.serviceType = serviceTypeMapping;
        testCase.modifiedAt = tc.modifiedAt;
        testCase.testScripts = tc.testScripts;
        testCase.snapshotId = snapshotId;
        testCase.services = tc.services;

        Promise.all(promiseInputResults).then(inputItems => {
          return testCase.inputs = inputItems;
        });

        Promise.all(promiseOutputResults).then(outputItems => {
          return testCase.outputs = outputItems;
        });

      }
    });
  });
  return testCase;
};

输入/输出是一个项目列表,如下所示:输入:[{名称:测试1",类型:字符串"},{名称:测试2",类型:数字"},]

The inputs/outputs is an list of item, like that: inputs:[ { name: "test1", type: "String" }, { name: "test2", type: "number" }, ]

我的 promise 生命周期有问题,这是当前流程1. 路线2. 函数 getTestCaseDetail3. resolve(addTestCasesV2(testCaseResult, snapshotId));4. addTestCasesV2 ==> 返回 testCase 但没有转到 2 promise.all 函数5. resolve(addTestCasesV2(testCaseResult, snapshotId));6. 路线7.返回2个promise.all函数8. end at return testCase.outputs = outputItems;

I have a problem with promise lifecycle, this is the current flow 1. Routes 2. function getTestCaseDetail 3. resolve(addTestCasesV2(testCaseResult, snapshotId)); 4. addTestCasesV2 ==> return testCase but without go to 2 promise.all functions 5. resolve(addTestCasesV2(testCaseResult, snapshotId)); 6. Routes 7. go back 2 promise.all functions 8. end at return testCase.outputs = outputItems;

详细流程请看图片(白色数字是当前流量,橙色数字是我的预期流量)

Please see the image to more detail flow (the white number is current flow, the orange number is my expect flow)

请多多指教.非常感谢.

Please advice me. Many thanks.

推荐答案

您的代码似乎不正确.如果 testcases 是一个包含多个项目的数组,你的 lodash.map 回调将被调用 testcases.length 时间.每次覆盖之前回调分配的 testCase.id.

Your code doesn't seem correct. If testcases is an array with more than one item, your lodash.map callback will be called testcases.length time. Each time overwriting testCase.id assigned in previous callback.

无论如何,我已经更正了您的代码,使其按您想要的运行顺序运行.我已经在各个地方记录了 ==step== 以寻求帮助.

Anyways, I have corrected bits of your code to make it in run order that you wanted. I have logged ==step== at various places for your help.

第一个函数:

function getTestCaseDetail(projectId, id, snapshotId) {
    let testCaseId = parseInt(id);
    return new Promise(((resolve, reject) => {
        return testCaseSchema.aggregate([
            { $match: { 'projectId': projectId, 'testCaseId': testCaseId } },
            {
                $lookup: {
                    from: snapshotInfoSchema.collection.collectionName,
                    localField: testCaseObj.SERVICE_ID,
                    foreignField: 'artifacts.id',
                    as: 'services',
                },
            },
            { $unwind: '$services' },
            {
                $match: {
                    'services.snapshot.id': snapshotId,
                }
            }
        ]).then(testCaseResult => {
            console.log('=======STEP 1=======');
            resolve(addTestCasesV2(testCaseResult, snapshotId));//=======STEP 2=======
            console.log('=======STEP 5=======')

        })
            .catch(err => {
                reject(err);
            })
    }));
}

第二个功能

const addTestCasesV2 = function (testcases, snapshotId) {
    console.log('=======STEP 2=======')
    const result = [];
    let serviceTypeMapping;
    let serviceName;
    let testCase = {
        id: '',
        testCaseId: '',
        name: '',
        serviceName: '',
        serviceType: '',
        modifiedAt: '',
        testScripts: '',
        snapshotId: '',
        services: '',
        inputs: [],
        outputs: [],
    };
    let promiseInputResults, promiseOutputResults;

    return Promise.resolve()
        .then(()=>{
            console.log('=======STEP 3=======');
            const testcasesList = lodash.map(testcases, (tc) => {
                const artifacts = lodash.map(tc.services.artifacts, (art) => {
                    if (art.id === tc.service_id) {
                        serviceTypeMapping = art.processType.serviceTypeName;
                        serviceName = art.name;
                        if (!commonUtil.isUndefined(art.processParameters)) {
                            if (!commonUtil.isUndefined(art.processParameters.input)) {
                                promiseInputResults = lodash.map(art.processParameters.input, (ip) => {
                                    let classId = commonUtil.getArtifactId(ip.classId);
                                    return objectType.getObjectTypeByClassId(snapshotId, classId)
                                });
                            }

                            if (!commonUtil.isUndefined(art.processParameters.output)) {
                                promiseOutputResults = lodash.map(art.processParameters.output, (ip) => {
                                    let classId = commonUtil.getArtifactId(ip.classId);
                                    return objectType.getObjectTypeByClassId(snapshotId, classId)
                                });
                            }
                        }
                        testCase.id = tc.testCaseId;
                        testCase.testCaseId = tc.testCaseId;
                        testCase.name = tc.name;
                        testCase.serviceName = serviceName;
                        testCase.serviceType = serviceTypeMapping;
                        testCase.modifiedAt = tc.modifiedAt;
                        testCase.testScripts = tc.testScripts;
                        testCase.snapshotId = snapshotId;
                        testCase.services = tc.services;


                        /*=======FOLLOWING IS NOT REQUIRED=======*/
                        // Promise.all([promiseOutputResults]).then(outputItems => {
                        //     return testCase.outputs = outputItems;
                        // });

                    }
                });
            });
            return Promise.all([promiseInputResults,promiseOutputResults]);
        })
        .then(inputItems => {//array of resolved values
            console.log('=======STEP 4=======');
            testCase.inputs = inputItems[0];
            testCase.outputs = inputItems[1];
            return testCase;
        })
};

现在您可以使用以下方法从第一个函数中提取测试用例:

Now you can use following to extract testcase from first function:

getTestCaseDetail(myProjectId, id, mySnapshotId)
    .then(testCase=>console.log(testCase))

JSfiddle 供您理解.

这篇关于在 node js 中使用 promise 时函数工作不正确的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆