Promise.method()函数没有像我期望的那样工作

时间:2016-11-28 10:03:17

标签: javascript node.js promise bluebird cryptojs

我正在编写一些加密两个用户之间通信通道的代码。 步骤如下

  • 检查mongoDb
  • 中是否存在该频道的密码
  • 如果是,请获取cipher并加密传入数据
  • 如果不是,请创建一个新密码,将其保存到mongoDb并加密传入数据

代码使用crypto模块,它是核心nodejs中为数不多的同步库之一

创建一个密码并将其作为承诺返回

cipher.createCipher = Promise.method((pw) => {
  if (!pw) {
    throw new Error('Passphrase must be provided');
  }
  return crypto.createCipher('aes192', pw);
});

使用Promise.method()

加密数据
cipher.encryptTextAsPromise = Promise.method((cipher, plainText) => {
  if (!( typeof plainText === 'string')) {
    throw new Error("2nd param must be plain text");
    let cipherText = '';
    cipher.on('readable', () => {
      var data = cipher.read();
      if (data)
        cipherText += data.toString('hex');
    });
    cipher.on('end', () => {
      return cipherText;
    });
    cipher.write(plainText);
    cipher.end();
  }
});

通过回调函数加密数据。

cipher.encryptText = (cipher, plainText, callback) => {
  if (!( typeof plainText === 'string')) {
    throw new Error("2nd param must be plain text");
  }
  try {
    let cipherText = '';
    cipher.on('readable', () => {
      var data = cipher.read();
      if (data)
        cipherText += data.toString('hex');
    });
    cipher.on('end', () => {
      callback(null, cipherText);
    });
    cipher.write(plainText);
    cipher.end();
  } catch (e) {
    callback(e, null);
  }
}

我无法将这两者联系在一起。我所拥有的是一个可怕的反模式,这比陷入回调地狱更糟糕

cipher.createCipher('secretWord')
  .then((data) => {
    cipher.encryptTextasPromise(data, 'hello world')
    .then((data) => {
      console.log(data);
    })
    .catch((err) => {
      console.log(err);
    })
  })
  .catch((err) => {
    console.log(err);
  })

mongoDbSearch(username)
  .then((data) => {
    if (data) {
      // Cipher exists, retrieve and encrypt
    }else {
      // Create new cipher and save
      someMongoSave()
        .then((data) => {
          // Cipher exists now, retrieve and encrypt
        })
    }
  })
  .catch((mongoErr) => {
    console.log(mongoErr);
  })

代码有点不完整,因为我仍在努力掌握这个概念。此外,我尝试将createCipherencryptTextAsPromise链接在数据中返回undefined。我已经尝试将这些作为正常回调写入,然后使用Promise.promisfyAll(),这感觉就像另一种反模式。

1 个答案:

答案 0 :(得分:3)

Promise.method似乎对createCipher有意义,但可能不适用于encryptTextAsPromise

此处有一个应该为您指明正确方向的版本,提取各种T.J. CrowderJaromanda X&和undefined&# 39;对这个问题的评论;请参阅代码注释以获取更多信息:

// For this one, `Promise.method` still makes sense (although doing it with
// your own promise is also perfectly reasonable)
cipher.createCipher = Promise.method(pw => {
  if (!pw) {
    throw new Error('Passphrase must be provided');
  }
  return crypto.createCipher('aes192', pw);
});

// For this one, your own promise makes sense
cipher.encryptTextAsPromise = (cipher, plainText) => {
  return new Promise(resolve => {
    if (!( typeof plainText === 'string')) {
      // It's fine to throw here (it will get converted into a rejection),
      // or add `reject` to the arguments list above and call
      // that and return instead:
      // reject(new Error("2nd param must be plain text"));
      // return;
      throw new Error("2nd param must be plain text");
    }
    let cipherText = '';
    cipher.on('readable', () => {
      var data = cipher.read();
      if (data)
        cipherText += data.toString('hex');
    });
    cipher.on('end', () => {
      resolve(cipherText);
    });
    cipher.write(plainText);
    cipher.end();
  });
};

// Usage:
cipher.createCipher('secretWord')
.then(data => cipher.encryptTextAsPromise(data, 'hello world'))
.then(data => console.log(data)) // See 1 below
.catch(err => console.log(err));

mongoDbSearch(username)
.then(data => data || someMongoSave(data)) // You pass `data` to `someMongoSave`, presumably?
.then(data => {
    // Cipher exists, retrieve and encrypt
})
.catch(mongoErr => {
    console.log(mongoErr);
});

另外,重新

if (!( typeof plainText === 'string')) {

JavaScript中有!==运算符。物权法'在说&#39 ;. ;-D