Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/461.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在筛选器操作中使用async/await在第一次等待调用后不等待完成_Javascript_Node.js_Asynchronous_Filter_Async Await - Fatal编程技术网

Javascript 在筛选器操作中使用async/await在第一次等待调用后不等待完成

Javascript 在筛选器操作中使用async/await在第一次等待调用后不等待完成,javascript,node.js,asynchronous,filter,async-await,Javascript,Node.js,Asynchronous,Filter,Async Await,对于特定的函数,需要从数据库中获取标签列表(RFID),但应检查各种表 问题的核心是长时间运行的操作在继续下一步之前没有等待完成 问题: 下面调用的代码运行如下(#数字对应下面代码中的数字): 调用getAllTags(),启动程序 await db.dbRfid.findAll()返回X个有效结果(不是Promise对象) 开始筛选有效对象上的调用&wait finish(wait-place),因为其中的一些函数调用是异步调用 调用const driverTags=wait tag.getD

对于特定的函数,需要从数据库中获取标签列表(RFID),但应检查各种表

问题的核心是长时间运行的操作在继续下一步之前没有等待完成

问题:

下面调用的代码运行如下(#数字对应下面代码中的数字):

  • 调用
    getAllTags()
    ,启动程序
  • await db.dbRfid.findAll()
    返回X个有效结果(不是
    Promise
    对象)
  • 开始筛选有效对象上的调用&wait finish(wait-place),因为其中的一些函数调用是异步调用
  • 调用
    const driverTags=wait tag.getDrivers();
  • 此时,人们希望此函数返回结果并继续执行下一个函数,即

    // #5
    const truckTags = await tag.getTrucks();
    
    实际上,对于每个
    allTags
    项,调用
    getDrivers()
    ,退出
    filter()
    ,然后通过执行以下命令继续代码:

    // #6
    if (pureTags) {
        return filteredTags;
    }
    
    问题:

    据我所知,我正在等待
    ing
    async
    操作,但筛选器似乎只接受/允许一个
    async
    操作

    我想我做错了什么,但我无法找出问题的原因。任何建议都将不胜感激

    下面的完整代码实现:

    打电话给某人

    const listOfTags = await getAllTags();
    
    特定标签要求(所有有效、未使用、已启用和未撤销的标签)

    问题代码:

    // #1
    const getAllTags = async (pureTags = false, unused = true, enabled = true, notRevoked = false) => {
        // #2
        let allTags = await db.dbRfid.findAll()
        // #3
        let filteredTags = await allTags.filter(async tag => {
            // check tag used
            if (unused) {
                // #4
                const driverTags = await tag.getDrivers();
                // #5
                const truckTags = await tag.getTrucks();
                const userTags = await tag.getUsers();
                if (driverTags.length > 0) {
                    return false;
                }
                if (truckTags.length > 0) {
                    return false;
                }
                if (userTags.length > 0) {
                    return false;
                }
            }
    
            // check tag enabled
            if (enabled && !tag.enabled) {
                return false;
            }
    
            // check tag revoked or return true
            return notRevoked && !tag.revoked;
        });
    
        // return tags as is
        // #6
        if (pureTags) {
            return filteredTags;
        }
    
        return filteredTags.map(tag => {
            return {
                id: tag.id,
                rfid: tag.rfid,
                expiryDate: tag.expiryDate,
                revoked: tag.revoked,
                enabled: tag.enabled
            }
        });
    }
    

    更新

    我应该提到:

  • 没有显示任何类型的“错误”来表示存在某种问题
  • .getDrivers()
    是一个创建的getter,它返回一个承诺

  • 更新2

    在evgeni fotia发表评论后

    我最初有这段代码,但是选择不包括它,因为它可能会使事情变得复杂。然而,这是我尝试添加的
    wait Promise.all()
    的原始代码


    请注意,在运行此更新或原始问题中的代码后,我看到调试器点击
    getDrivers()
    方法,然后(HTTP)响应被发送到客户端,并且仅在0.5~1s后我才看到
    getDrivers()
    方法返回并继续下一个方法。

    正如T.J.Chowder所评论的,您的中心问题是,您正在尝试对某些有时是布尔值,有时是承诺的东西进行
    .filter()

    您应该在不同的步骤中进行映射和筛选。我倾向于使用
    .then()
    语法,因此我的方法如下:

    const getAllTags = (pureTags = false, unused = true, enabled = true, notRevoked = false) => {
        return db.dbRfid.findAll()
            .then(allTags => allTags.map(tag => Promise.resolve(
                enabled === tag.enabled && notRevoked === !tag.revoked && Promise.all([
                    tag.getDrivers(), tag.getTrucks(), tag.getUsers()
                ]).then(results => results.some(r => r.length))
            ).then(ok => ok ? tag : null)))
            .then(pendingTags => Promise.all(pendingTags))
            .then(resolvedTags => resolvedTags.filter(tag => tag))
            .then(filteredTags => filteredTags.map(tag => pureTags ? tag : {
                id: tag.id,
                rfid: tag.rfid,
                expiryDate: tag.expiryDate,
                revoked: tag.revoked,
                enabled: tag.enabled
            }));
    };
    
    此代码的逻辑:

    • 从数据库获取标记
      产生
      承诺
      ,即对标记数组的承诺
    • 根据我们使用
      promise.resolve()
      产生
      承诺
    • 等待使用
      Promise.all()解析所有这些内部承诺

      产生了
      我相信@evgenifotia yup的相同问题,了解并尝试了
      承诺。所有
      。同样的结果,我选择只显示过滤器部分以更简洁。将发布
      承诺。所有
      作为更新,以解决任何问题或建议。您不能仅使用
      异步
      函数作为回调对于承诺不起任何作用的内容,
      async
      函数返回。
      filter
      只需检查返回是否为真实值——所有承诺实例都是真实值。如果您希望并行执行所有异步工作,可以使用
      map
      构建承诺数组,然后
      promise.all
      等待它们全部解决。如果您想一个接一个地执行这些操作,请使用
      for
      for of
      循环并
      推送到结果数组。FWIW,大致如下:@T.J.Crowder谢谢您的建议。我想使用
      map
      但是,我觉得这会降低性能,因为调用
      getDrivers()
      ,然后调用
      getTrucks()
      ,等等,不检查是否
      drivers.length>0
      。我在这里没有显示这一点,因为我修改了它来检查我是否得到了结果,但这是最初的意图。似乎我需要进行
      3x
      调用,无论我希望避免什么。感谢您的练习(我想我已经这样做了…几乎;)
      const getAllTags = async (pureTags = false, unused = true, enabled = true, notRevoked = false) => {
          let allTags = await db.dbRfid.findAll()
          let filteredTags = await Promise.all(
              // await allTags.filter(async tag => {      //tried the await here too - for good measure
              allTags.filter(async tag => {
                  // check tag used
                  if (unused) {
                      const driverTags = await tag.getDrivers();
                      const truckTags = await tag.getTrucks();
                      const userTags = await tag.getUsers();
                      if (driverTags.length > 0) {
                          return false;
                      }
                      if (truckTags.length > 0) {
                          return false;
                      }
                      if (userTags.length > 0) {
                          return false;
                      }
                  }
      
                  // check tag enabled
                  if (enabled && !tag.enabled) {
                      return false;
                  }
      
                  // check tag revoked or return true
                  return notRevoked && !tag.revoked;
              })
          );
      
          // return tags as is
          if (pureTags) {
              return filteredTags;
          }
      
          return filteredTags.map(tag => {
              return {
                  id: tag.id,
                  rfid: tag.rfid,
                  expiryDate: tag.expiryDate,
                  revoked: tag.revoked,
                  enabled: tag.enabled
              }
          });
      }
      
      const getAllTags = (pureTags = false, unused = true, enabled = true, notRevoked = false) => {
          return db.dbRfid.findAll()
              .then(allTags => allTags.map(tag => Promise.resolve(
                  enabled === tag.enabled && notRevoked === !tag.revoked && Promise.all([
                      tag.getDrivers(), tag.getTrucks(), tag.getUsers()
                  ]).then(results => results.some(r => r.length))
              ).then(ok => ok ? tag : null)))
              .then(pendingTags => Promise.all(pendingTags))
              .then(resolvedTags => resolvedTags.filter(tag => tag))
              .then(filteredTags => filteredTags.map(tag => pureTags ? tag : {
                  id: tag.id,
                  rfid: tag.rfid,
                  expiryDate: tag.expiryDate,
                  revoked: tag.revoked,
                  enabled: tag.enabled
              }));
      };