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

何时使用Promises推迟功能

慕志泽
2023-03-14
问题内容

我将Q节点库用于Promises,我认为这个问题也适用于Bluebird库。

语境

我需要对自己的自定义函数和node.js fs样式异步函数进行一些函数调用。

如果我正在调用这样的函数:

同步功能

do_something = function (input) {
  // assign variables, do other sync stuff 
}

并需要以上内容来执行before此功能:

同步功能

do_something_else = function (input) {
  // assign variable, do other sync stuff
}

并且then需要调用类似于以下内容的本机节点函数:

异步功能

writeData = function (obj, callback) {
  var deferred = Q.defer();
  fs.writeFile(obj.file, obj.datas, function (err, result) {
    if (err) deferred.reject(err);
    else deferred.resolve('write data completed');
  });
  return deferred.promise.nodeify(callback);
}

finally需要以上内容来执行before此功能:

同步功能

do_something_last = function (input) {
  // assign variable, do other sync stuff
}

为了使我的所有函数“递延”或答应知道,在这里要做的“正确”事情是什么,以便确保可以按顺序或以正确的顺序调用它们?像这样:

do_something(variable)
.then(do_something_else)
.then(writeData)
.then(do_something_last)
.done();

还是应该代替它并保持顺序(排序)?像这样:

var variable1 = 'test1.txt'
var variable2 = 'test2.txt'
var return_value = do_something(variable1);
var return_another_value = do_something_else(return_value); <--sync
writeData(return_another_value); <-- async function
var final_value = do_something_last(variable2);  <-- sync function
// could potentially have async calls again after a sync call
writeDataAgain(return_another_value); <-- async function

澄清说明

我的想法是,由于其中一些同步函数将需要在异步之后被触发,因此我需要使它们对Promise有所了解,以便保持顺序的顺畅,如下所示:

同步功能使承诺意识到

do_something = function (input) {
  var deferred = Q.defer();
  // assign variables, do other sync stuff 
  deferred.resolve(_output_result_);
  return deferred.promise;
}
do_something_else = function (input) {
  var deferred = Q.defer();
  // assign variables, do other sync stuff 
  deferred.resolve(_output_result_);
  return deferred.promise;
}
do_something_last = function (input) {
  var deferred = Q.defer();
  // assign variables, do other sync stuff 
  deferred.resolve('completed workflow');
  return deferred.promise;
}

这将允许我执行以下操作:

do_something(variable)
.then(do_something_else) <-- these need to execute before writeData
.then(writeData) <-- a async node fs call to writeFile
.then(do_something_last) <-- I need this to happen after the writeDate
.done();

阅读完反馈后,我想我真正要问的是:

如何创建函数工作流,混合非承诺同步和承诺感知的异步函数调用,同时保持执行的顺序(或顺序)?


问题答案:

只需这样做,并保持顺序如下:

writeData(return_another_value);
var final_value = do_something_last(variable2);

嗯,这根本就行不通,因为do_something_lastwriteData(…)诺言 解决
之后就没有这样说。它会在创建并返回承诺后立即开始。因此,如果您关心该特定顺序并想等到数据写入后,则 需要 使用then回调:

var final_promise = writeData(return_another_value).then(function(writeResult) {
    return do_something_last(variable2);
});

一般规则是:

  • 使同步功能同步-无需承诺
  • 使所有异步函数始终返回承诺
  • 仅在可能的最低级别使用延期付款

您可以将 同步函数放在then链中,非承诺的返回值(甚至抛出的异常)在它们中可以正常工作。因此,尽管您 可以 像这样写序列

Q('test1.txt')
.then(do_something)
.then(do_something_else)
.then(writeData)
.then(do_something_last.bind(null, 'test2.txt'))
.done();

看起来很奇怪。如果您do_something出于某种原因不打算在不久的将来使s异步,那么编写和阅读通常会更简单

writeData(do_something_else(do_something('test1.txt'))).then(function() {
    return do_something_last('test2.txt');
}).done();

诚然,有时写起来更具吸引力

somePromise()
.then(doSomethingSynchronous)
.then(doSomethingAsynchronous)

somePromise
.then(function(res) { return doSomethingAsynchronous(doSomethingSynchronous(res)); })

即使它们在 功能上相同 。选择您更喜欢且更一致的样式。



 类似资料:
  • 问题内容: 编辑 第一个答案是一个很好的答案,但是,正如该问题和另一个关于stackoverflow的问题中多次提到的那样,问题是服务和控制器在数据实际到达之前就运行它们的东西。 (对第一个答案的最后评论:) 是的,问题在于服务运行后API调用完成,并将所有内容返回给控制器,请参阅此处screencast.com/t/uRKMZ1IgGpb7 …这是我的BASE问题,如何在所有部件上等待数据发送到

  • 问题内容: 我有一些要更新的旧Node.js代码。在此过程中,我正在设计新模块以与旧代码一起使用。我发现现在,与我最初写这篇文章时相反,我更多地依赖使用ES6 Promise,而不是回调。所以现在我混合了一些函数,这些函数返回Promise和一些采用回调-这很乏味。我认为最终应该重构使用诺言。但是在那之前… 在什么情况下首选promise和回调在哪里? 在某种情况下,回调能比承诺更好地处理吗,反之

  • 问题内容: 假设我有以下功能 如规范中所述: 每次执行“ defer”语句时,将照常评估调用的函数值和参数并重新保存,但不会调用实际函数。 显然,函数执行结束时将输出零。但是,如果我想打印出变量的最终值该怎么办? 我提出了以下解决方案: 所以我想知道是否有更好的方法来解决此问题。 问题答案: 如果defer有参数,则在defer语句的行对其进行评估;以下代码段对此进行了说明,其中defer将显示0

  • 我为我的草图创建了一个简单的延迟函数,并试图使用它,但似乎渲染停止了,也就是说,有一个简单的灰色屏幕,然后一切都被一次渲染。 有人能告诉我我在哪里吗出错了?到底发生了什么? 如何在内部定义绘制()和设置()?我知道,set()是一个一次性的渲染和绘制(),就像一个无限的循环。 代码:

  • 在轻推邮件功能中成功配置邮箱后,可利用轻推进行邮件接收和发送。 操作办法:我-邮件-配置邮件 查看邮件-发送邮件

  • 问题内容: 在过去的几天里,我一直在学习React,研究一些有关编写不同元素的不同方式的教程和说明。但是,我最想知道的是- 更新/覆盖组件属性的功能。 例如,假设我有一个包含以下内容的类: 这个例子让我从API获取图像。 鉴于我已经执行了此函数的获取,映射和返回操作-然后,我将使用在API调用中获得的结果来更新状态数组。 我的问题源于我所见过的关于如何更新/覆盖图片状态属性的不同方法。 我看到它以