什么是完全的承诺

时间:2018-11-25 17:59:21

标签: javascript node.js mongoose

我偶然发现行中的猫鼬文档

  

猫鼬查询不是承诺。他们有一个.then()函数   和async / await为方便。如果您需要完整的承诺,   使用.exec()函数。

在此示例中

var query = Band.findOne({name: "Guns N' Roses"});
assert.ok(!(query instanceof Promise));

// A query is not a fully-fledged promise, but it does have a `.then()`.
query.then(function (doc) {
  // use doc
});

// `.exec()` gives you a fully-fledged promise
var promise = query.exec();
assert.ok(promise instanceof Promise);

promise.then(function (doc) {
  // use doc
});

现在,当他们说全面承诺时,我并没有理解他们的意思,就像对我.then()来说应该是一种提倡,然后它还允许异步和等待。

那么有人可以向我解释完全承诺的意思是什么吗?

参考链接:https://mongoosejs.com/docs/promises.html#queries-are-not-promises

2 个答案:

答案 0 :(得分:6)

这意味着,根据Promises/A+ spec的定义,查询返回的值是 thenables ,而不是实际的Promise实例。这意味着它们可能不具有Promise的所有功能(例如,catchfinally方法)。实际的Promise实例将是“完全成熟的”承诺。

英语术语“ fully-fledged”表示“完整”或“完全开发”。它来自鸟类学(或至少与鸟类有关的术语):一只成年羽毛的小鸡(一只幼鸟)“出雏”;如果它的所有成年羽毛都完全覆盖了down底毛,则说明它是成熟的。

答案 1 :(得分:0)

@ T.J。 Crowder的回答确实帮助我澄清了很多事情(我也碰到了这个帖子,因为我也很困惑),我只想在这里补充一点:)

传统上,then()方法返回Promise。它最多包含两个参数:Promise的成功情况(onFulfilled)和失败情况(onRejected)的回调函数。然而,罐头食品无法以这种方式工作。我们将无法传递两个回调函数,例如我们如何使用“完全承诺”。用一些代码来说明这一点:

UserModel.find().exec((err, users) => {
  if (err) return res.status(400).send(err);
  res.status(200).json({
    success: true,
    users,
  });
});

这很好用,因为我们为成功案例和失败案例传入的两个回调函数称为err(失败案例),而成功/结果案例称为用户。 请注意,Mongoose中的所有回调都使用以下模式:callback(error,result)-这与MDN Web文档中指定的回调函数的顺序不同。现在,如果我们运行同一段代码,但是用then()替换exec()就像这样:

UserModel.find().then((err, users) => {
  if (err) return res.status(400).send(err);
  res.status(200).json({
    success: true,
    users,
  });
});

这将返回400错误的请求状态。

这是因为猫鼬查询不是“完整的承诺”,因此我们不能在查询后链接.then(),然后期望它像真正的承诺一样。

但是,根据我的尝试,实际上,您仍然可以像这样使用.catch()进行错误处理:

// {_id:1} is included to make this fail
UserModel.find({ _id: 1 })
  .then((users) => {
    res.status(200).json({
      success: true,
      users,
    });
  })
  .catch((err) => {
    res.status(400).send(err);
  });