何时使用 Promises 延迟函数 [英] When to make a function deferred using Promises

查看:22
本文介绍了何时使用 Promises 延迟函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm using the Q node library for Promises, question I think can apply to the Bluebird lib as well.

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

I have a few function calls to make to both my own custom functions and node.js fs style async functions.

如果我要调用这样的函数:

if I'm making a call to a function like this:

同步功能

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

并且需要上面发生before这个函数:

and need the above to take place before this function:

同步功能

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

then需要调用一个类似于:

and then need to call a native node function similar to:

异步函数

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这个函数:

and finally need the above to take place before this function:

同步功能

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

问题

在这里做的正确"的事情是让我的所有功能延迟"或承诺知道,以便我可以确保按顺序或正确的顺序调用它们吗?像这样:

Question

Is the 'right' thing to do here, to make all my functions 'deferred' or promise aware so I can make sure that they are called in sequence or in the correct order? like so:

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

还是我应该这样做并保持顺序(排序)?像这样:

or should I just do this instead and keep the ordering (sequencing)? Like so:

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 以保持顺序正确,如下所示:

Clarifications

What I thought was since some of these sync functions are going to need to be fired after the async, I needed to make them Promise aware in order to keep the sequence straight, like so:

同步功能使承诺意识到

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();

在我阅读了反馈之后,我想我真正想问的是:

After the feedback i've read, i guess what it seems like i'm really asking is:

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

How do I create a function workflow, mixing non-promise sync and promise-aware async function calls, all the while keeping the ordering (or sequencing) of execution?

推荐答案

只需这样做并保持这样的顺序:

just do this instead and keep the ordering like so:

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

好吧,这根本行不通,因为 do_something_lastwriteData(…) 承诺被解决后不会被调用.它会在承诺创建并返回后立即开始.因此,如果您关心该特定顺序并希望等到数据写入,那么您需要使用带有回调的 then :

Well, that simply won't work, as do_something_last is not called after the writeData(…) promise is resolved. It'll just start right after the promise is created and returned. So if you care about that particular order and want to wait until the data is written, then you need to use then with a callback:

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

<小时>

一般规则是:


The general rules are:

  • 使同步函数同步 - 无需承诺
  • 让所有异步函数总是返回一个promise
  • 对于承诺
  • 仅在尽可能低的级别使用延迟
  • make synchronous functions synchronous - no need for promises
  • make all asynchronous functions always return a promise
  • use deferreds only at the lowest possible level for promisification

您可以将同步函数放在then中,非承诺返回值(甚至抛出的异常)在其中运行良好.所以虽然你可以

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

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

it looks rather odd. If you don't plan to make the do_somethings asynchronous in the near future for some reason, it's often simpler to write and read

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

诚然,有时写作更有吸引力

Admittedly, it's sometimes more appealing to write

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

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

即使它们功能相同.选择你更喜欢、更一致的风格.

even though they are functionally identical. Choose the style that you like better and that is more consistent.

这篇关于何时使用 Promises 延迟函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆