nodejs 过滤对象数组,其中过滤部分在异步函数中完成

nodejs filtering an array of objects where the filtering is partially done in an async function

我看过很多类似的问题,也试过一堆代码。不幸的是,我没有将我的代码发送到 运行 :-(

因此,情况如下:在 node.js 服务器的路由中,我必须使用经过过滤的对象数组进行响应。不幸的是,无论我做什么,我总是得到一个空数组 [] 。在我看来,过滤器有点棘手,因为它由字符串比较和对库函数的异步调用组成。通过控制台输出,我可以清楚地看到找到了正确的元素,但同时我看到我已经收到了对象...

这里有一些代码可以证明我的挑战:

let testArray = [
  {
    id: 'stringId1',
    data: {
      someDoc: {
        moreContent: 'Some random content',
        type: 'noInterest'
      }
    }
  },
  {
    id: 'stringId2',
    data: {
      someDoc: {
        moreContent: 'Some random content',
        type: 'ofInterest'
      }
    }
  },
  {
    id: 'stringId3',
    data: {
      someDoc: {
        moreContent: 'Some random content',
        type: 'ofInterest'
      }
    }
  }
]

// code from a library. Can't take an influence in it.
async function booleanWhenGood(id) {
  if (id in some Object) {
    return { myBoolean: true };
  } else {
    return { myBoolean: false };
  }
}

// Should return only elements with type 'ofInterest' and that the function booleanWhenGood is true
router.get('/', function(res,req) {
  tryOne(testArray).then(tryOneResult =>{
    console.log('tryOneResult', tryOneResult);
  });
  tryTwo(testArray).then(tryTwoResult => {
    console.log("tryTwoResult ", tryTwoResult);
  });

  result = [];
  for (const [idx, item] of testArray.entries() ) {
    console.log(idx);
    if (item.data.someDoc.type === "ofInterest") {
      smt.find(item.id).then(element => {
        if(element.found) {
          result.push(item.id);
          console.log("ID is true: ", item.id);
        }
      });
    }

    if (idx === testArray.length-1) {
      // Always returns []
      console.log(result);
      res.send(result);
    }
  }
})


// A helper function I wrote that I use in the things I've tried
async function myComputeBoolean(inputId, inputBoolean) {
  let result = await booleanWhenGood(inputId)
  
  if (result.myBoolean) {
    console.log("ID is true: ", inputId);
  }

  return (result.myBoolean && inputBoolean);
}

// A few things I've tried so far:
async function tryOne(myArray) {
  let myTmpArray = []

  Promise.all(myArray.filter(item => {
    console.log("item ", item.id);
    myComputeBoolean(item.id, item.data.someDoc.type === "ofInterest")
    .then(myBResult => {
      console.log("boolean result", myBResult)
      if (myBResult) {
        tmpjsdlf.push(item.id);
        return true;
      }
    })
  })).then(returnOfPromise => {
    // Always returns [];
    console.log("returnOfPromise", myTmpArray);
  });

  // Always returns []
  return(myTmpArray);
}

async function tryTwo(myArray) {
  let myTmpArray = [];
  myArray.forEach(item => {
    console.log("item ", item.id);
    myCompuBoolean(item.id, item.data.someDoc.type === "ofInterest")
    .then(myBResult => {
      console.log("boolean result", myBResult)
      if (myBResult) {
        myTmpArray.push(item.did);
      }
    })
  });

  Promise.all(myTmpArray).then(promiseResult => {
    return myTmpArray;
  });
}

在这种情况下异步编程对我来说真的很难...你能帮我搞定吗运行ning?

我没有仔细检查你的尝试,但我相信你遇到了一些竞争条件(你打印 return 并在承诺解决之前打印数组)。

但是,您始终可以使用常规的 for 循环来过滤可迭代对象。像这样:

let testArray = [
    {
        id: 'stringId1',
        data: {
            someDoc: {
                moreContent: 'Some random content',
                type: 'noInterest'
            }
        }
    },
    {
        id: 'stringId2',
        data: {
            someDoc: {
                moreContent: 'Some random content',
                type: 'ofInterest'
            }
        }
    },
    {
        id: 'stringId3',
        data: {
            someDoc: {
                moreContent: 'Some random content',
                type: 'ofInterest'
            }
        }
    }
]

async function booleanWhenGood(id) {
    if (id in { 'stringId1': 1, 'stringId2': 1 }) { // mock object
        return { myBoolean: true };
    } else {
        return { myBoolean: false };
    }
}

async function main() {
    let filtered = []
    for (item of testArray)
        if ((await booleanWhenGood(item.id)).myBoolean && item.data.someDoc.type === 'ofInterest')
            filtered.push(item)
    console.log('filtered :>> ', filtered);
}

main()