首页 > 解决方案 > Promises 如何在 node/feathersjs 中工作?

问题描述

我做了这样的功能,应该检查当前用户是否禁止模块。如果是 - 返回错误,如果不是 - 然后让他做其余的钩子/继续到 api 路由。此方法在服务挂钩中调用。

function isAppForbidden(hook) {
  return new Promise((resolve, reject) => {
    hook.app.services.settings.find({
      query: {
        $limit: 1,
        $sort: {
          createdAt: -1
        }
      },
      user: {
        roleId: hook.params.user.roleId
      }
    }).then(res => {
      if(res.data.length > 0) {
        let userHiddenApps = hook.params.user.hiddenApps || [];
        let globalHiddenApps = res.data[0].forbiddenApps || [];
        if (userHiddenApps.indexOf('qualitydocs') >= 0 || globalHiddenApps.indexOf('qualitydocs') >= 0) {
          reject(new errors.Forbidden()); //throws error for forbidden moduels
        }
        resolve();
      }
    })
  })
}

before: {
    all: [
      authenticate('jwt'),
      hook => includeBefore(hook),
      hook => isAppForbidden(hook)
    ],
    find: [],
    get: [],
    create: [(hook) => {
      hook.data.authorId = hook.params.user.id;
    }],
    update: [],
    patch: [],
    remove: []
  },

在我的本地机器上一切正常。如果模块被禁止,我会收到禁止错误,如果没有,那么我会从路由中获取数据。但是在我的生产机器上它不能那样工作,如果模块不被禁止(没有错误)我没有收到任何响应,就好像它在'resolve()'部分结束了某种循环?可能吗?你觉得这个承诺不错吗?

我知道它的奇怪问题,但我不知道从哪里开始,因为它在本地工作得非常好并且在生产中没有错误(除了它破坏了整个应用程序,不再有响应,直到你重新加载页面)。

标签: node.jsexpresses6-promisefeathersjs

解决方案


问题是,如果res.data.length <= 0你的承诺永远不会解决。一般来说,当使用 Feathers 功能时,你永远不必调用new Promise自己,因为一切都已经返回了 Promise。您可以使用async/await让您的生活更加轻松,这将使代码更易于遵循并完全避免您的问题:

async function isAppForbidden(hook) {
  const res = await hook.app.service('settings').find({
    query: {
      $limit: 1,
      $sort: {
        createdAt: -1
      }
    },
    user: {
      roleId: hook.params.user.roleId
    }
  });

  if(res.data.length > 0) {
    let userHiddenApps = hook.params.user.hiddenApps || [];
    let globalHiddenApps = res.data[0].forbiddenApps || [];

    if (userHiddenApps.indexOf('qualitydocs') >= 0 || globalHiddenApps.indexOf('qualitydocs') >= 0) {
      throw new errors.Forbidden(); //throws error for forbidden moduels
    }
  }

  return hook;
}

before: {
    all: [
      authenticate('jwt'),
      includeBefore,
      isAppForbidden
    ],
    find: [],
    get: [],
    create: [(hook) => {
      hook.data.authorId = hook.params.user.id;
    }],
    update: [],
    patch: [],
    remove: []
  },

推荐阅读