当前位置: 首页 > 面试题库 >

我应该在Promise中使用`return`吗?

艾飞宇
2023-03-14
问题内容
function saveToTheDb(value) {  
  return new Promise(function(resolve, reject) {
    db.values.insert(value, function(err, user) { // remember error first ;)
      if (err) {
        return reject(err); // don't forget to return here
      }
      resolve(user);
    })
  }
}

这是我从这里看到的代码。我对return关键字感到困惑。

对于resolve(user);,我需要return

对于reject(user);,我需要return


问题答案:

无需在new Promise()回调中使用return语句。Promise构造函数不期望回调返回任何类型的返回值。

因此,return在该回调中使用语句的原因仅是为了控制该函数中的执行流程。
如果您希望回调内部的执行完成而又不执行该回调中的任何其他代码,则可以return;在此时发出a 。

例如,您可以这样编写代码,而无需return声明:

function saveToTheDb(value) {  
  return new Promise(function(resolve, reject) {
    db.values.insert(value, function(err, user) { 
      if (err) {
        reject(err);
      } else {
        resolve(user);
      }
    });
  }
}

在这种情况下,您使用了if / else子句来确保函数中的控制流采用正确的路径,并且return不需要或不使用它。

分发这样的异步函数时,常见的快捷方式是:

function saveToTheDb(value) {  
  return new Promise(function(resolve, reject) {
    db.values.insert(value, function(err, user) { 
      if (err) return reject(err);
      resolve(user);
    });
  }
}

这在功能上与先前的代码块没有什么不同,但是它的键入更少且更紧凑。return前面的语句reject(err);仅出于控制流的原因,以防止resolve(user);在发生错误的情况下执行该语句,因为所需的控制流将被调用reject(err),然后不在回调中执行其他任何操作。

实际上,return在此特定情况下,实际上甚至不需要最后一个语句中的语句,因为执行诺resolve()后操作reject()将不会做任何事情,因为将诺言锁存到首先解析或拒绝发生的任何事件。但是,通常认为执行不必要的代码是较差的做法,因此许多人会认为最好使用控制结构流,例如if/elsereturn仅执行所需的代码。

因此,从技术上讲,这也是可行的,但由于它执行了不必要的代码并且结构也不太清晰,因此不被视为最佳实践:

function saveToTheDb(value) {  
  return new Promise(function(resolve, reject) {
    db.values.insert(value, function(err, user) {
      if (err) reject(err);
      resolve(user);
    });
  }
}

仅供参考,您在此处执行的操作称为“
promisifying”,它使常规的异步函数(与回调一起使用)成为返回promise的函数。有一些库和函数可以在一个函数调用中为您“分配”一个函数或函数的整个对象(例如,整个API),因此您不必手动执行此操作。例如,我经常使用Bluebird,它提供Promise.promisify()了一个函数的Promise.promisifyAll()承诺或将一个对象或原型上的所有方法实现了承诺。这非常有用。例如,您可以通过以下方式获得整个fs模块的承诺版本:

var Promise = require('bluebird');
var fs = Promise.promisifyAll(require('fs'));

然后,您可以使用返回承诺的方法,例如:

fs.readFileAsync("file.txt").then(function(data) {
    // do something with file.txt data here
});


 类似资料:
  • 问题内容: 我在JS应用程序中使用异步函数,这些函数包装有接收回调输入的我自己的函数。当我调用回调函数时,是否需要使用“ return”关键字?有关系吗?有什么不同? 例如: PS:我正在使用javascript编写混合移动应用。 问题答案: 如果只有一条路径通过函数,则可以将两种形式互换使用。当然,该函数的返回值将在没有返回的情况下是不确定的,但是您的调用代码可能仍未使用它。 没错 实际上相当于

  • 我在一个在线订餐应用程序中使用Redux和React。 当用户从购物篮中删除一个商品时,我需要向服务器发出一个XHR请求,以计算购物篮的新总价。当这个XHR完成时,我更新redux存储并呈现新的价格。我使用Redux thunk来管理这个异步操作。 有一个问题是,用户连续快速地从购物篮中取出两件物品。用户删除第一项,我启动XHR以获得新价格。然后,用户单击一个按钮以删除第二个项目,并启动第二个XH

  • 问题内容: 我们的网站目前正在使用jQuery库,每月的访问量约为100万。我们希望包括以API为中心的方法,因此决定转向Javascript MVC并为此选择了angularJS。 现在我的问题是,我应该在Angular顶部使用jQuery,以便我需要重写最少的DOM操作代码,还是应该以Angular方式重写所有内容?我们使用的是jQuery插件,例如plupload,jQuery UI。等在网

  • 问题内容: 给定下面的代码示例,行为上是否有任何差异,如果有,这些差异是什么? 据我了解,第一个将在异步函数中进行错误处理,并且错误将从异步函数的Promise中冒出来。但是,第二个需要较少的滴答声。它是否正确? 此片段只是返回Promise供参考的常用功能。 问题答案: 在大多数情况下,和之间没有可观察到的差异。这两个版本的观察行为完全相同(但根据实现的不同,该版本可能会使用更多的内存,因为可能

  • 问题内容: 有时是有用的,例如,如果我为网站上的所有链接(例如选择器)定义了通用样式,但是当我要覆盖某些规则时,可以有以下选择: 使用更具体(更长)的选择器 采用 哪种方法更好,可能有一些指导原则? 问题答案: 使用非常,非常谨慎- 它会覆盖刚才的一切,甚至是内联样式和混乱在低于显而易见的方式与样式规则“梯级”,让CSS的名字。它很容易使用不当,而且容易成倍增加,尤其是在滥用时。您可以轻松地得出一

  • 问题内容: 我不太清楚当我这样说时会做什么: 我可以稍微了解使用它的原因,因为它不浏览整个数据库表以更新字段,而是仅更新新添加的记录。如我错了请纠正我。 所以我想做的是使用这样创建索引: 一旦执行此操作,文档就根本不会上传到索引。我要去哪里错了? 任何帮助,不胜感激。 问题答案: 如果您的表中有一个时间戳列(例如),则最好使用它代替ID号。这样,当记录更新时,您也可以修改该时间戳,输入插件将提取记