承诺待定不会解决或拒绝

时间:2020-04-15 15:26:26

标签: javascript node.js azure-functions

我有一个更新密码功能,可以更新用户密码并删除生成的一次性URL。当前,它正在对前端返回一个空响应,变量updatedResult表示Promise待处理,因此这似乎是空响应的问题。当我执行代码时,这就是输出。我在两个地方添加了updatedResult console.log()输出,以引用其输出: 代码也有效。我的密码已更新,可以使用新密码登录,但是由于这个承诺问题,我只是没有得到响应。

USER IS $2b$10$VBjWX9KPX2dVMVcdFASFSDFbG9XjONHqe0bJDjKUvY/S7/gSC4sPbhIekBTa
[4/15/2020 3:21:22 PM] JSON.stringify(payload)
[4/15/2020 3:21:22 PM] {"id":"5e92133edab88409dc4d1219","email":"bob@gmail.com","iat":1586963845,"exp":1586963945}
[4/15/2020 3:21:22 PM] updated Result From Here
[4/15/2020 3:21:22 PM] Promise { <pending> }
[4/15/2020 3:21:22 PM] Executed 'Functions.PATCH-PWReset-Update' (Succeeded, Id=2fd8968c-fcad-4db0-a5e4-3ab7f41700e6)
[4/15/2020 3:21:22 PM] Executed HTTP request: {
[4/15/2020 3:21:22 PM]   "requestId": "5ae5c23c-3861-4594-81f3-18de4a8631d1",
[4/15/2020 3:21:22 PM]   "method": "PATCH",
[4/15/2020 3:21:22 PM]   "uri": "/api/PATCH-PWReset-Update",
[4/15/2020 3:21:22 PM]   "identities": [
[4/15/2020 3:21:22 PM]     {
[4/15/2020 3:21:22 PM]       "type": "WebJobsAuthLevel",
[4/15/2020 3:21:22 PM]       "level": "Admin"
[4/15/2020 3:21:22 PM]     }
[4/15/2020 3:21:22 PM]   ],
[4/15/2020 3:21:22 PM]   "status": 200,
[4/15/2020 3:21:22 PM]   "duration": 722
[4/15/2020 3:21:22 PM] }
[4/15/2020 3:21:22 PM] updatedResult
[4/15/2020 3:21:22 PM] Promise { <pending> }
[4/15/2020 3:21:25 PM] Host lock lease acquired by instance ID '000000000000000000000000179CDB79'.

我为什么得到Promise <pending>


var Url = require('../models/url');
var User = require('../models/user');
const jwt = require("jsonwebtoken");
const bcrypt = require("bcrypt");
var mongoose = require('mongoose');

mongoose
  .connect(
    "mongodb://" +
    process.env.COSMOSDB_HOST +
    ":" +
    process.env.COSMOSDB_PORT +
    "/" +
    process.env.COSMOSDB_DBNAME +
    "?ssl=true&replicaSet=globaldb",
    {
      auth: {
        user: process.env.COSMOSDB_USER,
        password: process.env.COSMOSDB_PASSWORD
      }
    }
  )
  .then(() => console.log("Connection to CosmosDB successful"))
  .catch(err => console.error(err));



module.exports = function (context, req) {



  // TODO: Fetch user from database using
  User.findById(req.body.id).then((res) => {
    console.log("USER IS " + res.password);
    var secret = res.password + "-" + res.passwordCreated.getTime();
    var payload = jwt.decode(req.body.token, secret);


    console.log("JSON.stringify(payload)")
    console.log(JSON.stringify(payload))


    try {
      const updatedResult = new Promise((resolve, reject) => {
        bcrypt.hash(req.body.password, 10, function (error, hash) {
          if (error) {
            reject(error);
          }
          newPasswordHash = hash;
          // res.sendStatus(401);

          try {
            const updated = User.updateOne({ password: newPasswordHash });
            resolve(updated);
          } catch (err) {
            reject(err);
          }
          reject();
        });

      });
      let generatedUrl = `http://localhost:4200/resetpassword/${req.body.id}/${req.body.token}`;

      Url.findOneAndDelete({ url: generatedUrl }).then(documents => {
        console.log("updatedResult");
        console.log(updatedResult);
        if (documents) {

          context.res = {

            status: 200,

            body: {
              message: "URL DELETED"
            },

            headers: {
              "Access-Control-Allow-Credentials": "true",
              "Access-Control-Allow-Origin": "*",
              "Access-Control-Allow-Methods": "PATCH, OPTIONS",
              "Access-Control-Allow-Headers": "Content-Type, Set-Cookie",
              "Access-Control-Max-Age": "86400",
              "Vary": "Accept-Encoding, Origin",
              "Content-Type": "application/json"
            }

          };

          context.done();

        }


      }).catch((err) => {
        console.log("ERR");
        console.log(err);

        context.res = {

          status: 500,

          body: {
            message: "ONE TIME URL DELETE ERROR",
            error: err
          },

          headers: {
            "Access-Control-Allow-Credentials": "true",
            "Access-Control-Allow-Origin": "*",
            "Access-Control-Allow-Methods": "PATCH, OPTIONS",
            "Access-Control-Allow-Headers": "Content-Type, Set-Cookie",
            "Access-Control-Max-Age": "86400",
            "Vary": "Accept-Encoding, Origin",
            "Content-Type": "application/json"
          }

        };

        context.done();


      });
      console.log("updated Result From Here");
      console.log(updatedResult);
      context.json = {

        status: 200,

        body: {
          message: "Password updated!"
        },

        headers: {
          "Access-Control-Allow-Credentials": "true",
          "Access-Control-Allow-Origin": "*",
          "Access-Control-Allow-Methods": "PATCH, OPTIONS",
          "Access-Control-Allow-Headers": "Content-Type, Set-Cookie",
          "Access-Control-Max-Age": "86400",
          "Vary": "Accept-Encoding, Origin",
          "Content-Type": "application/json"
        }

      };

      context.done();


    } catch (err) {

      console.log("ER1R");
      console.log(err);


      context.res = {

        status: 500,

        body: {
          message: "ONE TIME URL DELETE error",
          error: err
        },

        headers: {
          "Access-Control-Allow-Credentials": "true",
          "Access-Control-Allow-Origin": "*",
          "Access-Control-Allow-Methods": "PATCH, OPTIONS",
          "Access-Control-Allow-Headers": "Content-Type, Set-Cookie",
          "Access-Control-Max-Age": "86400",
          "Vary": "Accept-Encoding, Origin",
          "Content-Type": "application/json"
        }

      };

      context.done();


    }

  }).catch((err) => {

    context.res = {

      status: 500,

      body: {
        message: "PW Update Failed!"
      },

      headers: {
        "Access-Control-Allow-Credentials": "true",
        "Access-Control-Allow-Origin": "*",
        "Access-Control-Allow-Methods": "PATCH, OPTIONS",
        "Access-Control-Allow-Headers": "Content-Type, Set-Cookie",
        "Access-Control-Max-Age": "86400",
        "Vary": "Accept-Encoding, Origin",
        "Content-Type": "application/json"
      }

    };

    context.done();


  })

};

2 个答案:

答案 0 :(得分:1)

我从您的代码中得到的是:

  • 您正在寻找用户。
  • 然后并行更新密码和一次性URL。

您收到未决错误,因为您没有解决在寻找用户时创建的承诺。

const updatedResult = new Promise((resolve, reject) => {
   bcrypt.hash(req.body.password, 10, function(error, hash) {
     if (error) {
       reject(error);
     }
     newPasswordHash = hash;
     // res.sendStatus(401);

     try {
       const updated = User.updateOne({ password: newPasswordHash });
       resolve(updated);
     } catch (err) {
       reject(err);
     }
     reject();
   });
});

以一种干净的方式进行操作,我建议创建一个单独的函数并从那里调用db操作。像这样:

module.exports = function(context, req) {
  // TODO: Fetch user from database using
  User.findById(req.body.id)
    .then((res) => {
      console.log('USER IS ' + res.password);
      var secret = res.password + '-' + res.passwordCreated.getTime();
      var payload = jwt.decode(req.body.token, secret);
      return Promise.all([updatePassword(req), deleteOneTimeUrl(req)]);
    })
    .then((result) => {
      context.json = {
        status: 200,

        body: {
          message: 'Password updated!',
        },

        headers: {
          'Access-Control-Allow-Credentials': 'true',
          'Access-Control-Allow-Origin': '*',
          'Access-Control-Allow-Methods': 'PATCH, OPTIONS',
          'Access-Control-Allow-Headers': 'Content-Type, Set-Cookie',
          'Access-Control-Max-Age': '86400',
          Vary: 'Accept-Encoding, Origin',
          'Content-Type': 'application/json',
        },
      };

      context.done();
    })
    .catch((err) => {
      context.res = {
        status: 500,

        headers: {
          'Access-Control-Allow-Credentials': 'true',
          'Access-Control-Allow-Origin': '*',
          'Access-Control-Allow-Methods': 'PATCH, OPTIONS',
          'Access-Control-Allow-Headers': 'Content-Type, Set-Cookie',
          'Access-Control-Max-Age': '86400',
          Vary: 'Accept-Encoding, Origin',
          'Content-Type': 'application/json',
        },
      };
      if (err.errorCode == 'DELETE_FAIL')
        context.res.body = {
          message: 'ONE TIME URL DELETE ERROR',
          error: err.error,
        };
      else
        context.res.body = {
          message: 'PW Update Failed!',
        };

      context.done();
    });
};

function deleteOneTimeUrl(req) {
  let generatedUrl = `http://localhost:4200/resetpassword/${req.body.id}/${req.body.token}`;
  return Url.findOneAndDelete({ url: generatedUrl })
    .then(res => { return Promise.resolve(res);})
    .catch((error) => {
      return Promise.reject({ errorCode: 'DELETE_FAIL', error: error });
    });
}

function updatePassword(req) {
  return new Promise((resolve, reject) => {
    bcrypt.hash(req.body.password, 10, function(error, hash) {
      if (error) {
        reject({ errorCode: 'UPDATE_FAIL', error: error });
      }
      newPasswordHash = hash;
      // res.sendStatus(401);
      try {
        const updated = User.updateOne({ password: newPasswordHash });
        resolve(updated);
      } catch (err) {
        reject({ errorCode: 'UPDATE_FAIL', error: error });
      }
      reject({ errorCode: 'UPDATE_FAIL' });
    });
  });
}

答案 1 :(得分:0)

Url.findOneAndDelete({ url: generatedUrl }).then(documents => {
  console.log("updatedResult");
  console.log(updatedResult);

您必须等待updateResult Promise,您可以这样做

updatedResult.then(value => {
// ... rest of logic ...
})

或等待两个承诺完成

Promise.all([
Url.findOneAndDelete({ url: generatedUrl }),
updatedResult
]).then(([document, value]) => {
// ... rest of logic ...
})