当要使用承诺延期功能 [英] When to make a function deferred using Promises

查看:123
本文介绍了当要使用承诺延期功能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用的承诺在Q节点库的问题,我觉得可以向蓝鸟LIB为好。

上下文

我有几个函数调用,使这两个我自己的自定义功能和node.js的 FS 风格的异步功能。

如果我打电话给这样的功能:


  

同步功能


  do_something =功能(输入){
  //分配变量,做其他的东西同步
}

和需要上面发生之前此功能:


  

同步功能


  do_something_else的=功能(输入){
  //变量赋值,做其他的东西同步
}

然后需要调用类似于本地节点的功能:


  

异步函数


  writeData =功能(OBJ,回调){
  VAR递延= Q.defer();
  fs.writeFile(obj.file,obj.datas,功能(错了,结果){
    如果(ERR)deferred.reject(ERR);
    其他deferred.resolve('完成写入数据');
  });
  返回deferred.promise.nodeify(回调);
}

最后需要上面发生之前此功能:


  

同步功能


  do_something_last =功能(输入){
  //变量赋值,做其他的东西同步
}

问题

是正确的事情在这里,让我的所有功能延迟或许诺知道这样我就可以确保他们被称为顺序或按正确的顺序?
像这样:

  do_something(变量)
。然后(do_something_else的)
。然后(writeData)
。然后(do_something_last)
.done();

或者我应该只是做这个代替,并保持排序(排序)?像这样:

  VAR变量1 ='test1.txt的'
VAR变量2 ='的test2.txt'
VAR RETURN_VALUE = do_something(变量1);
VAR return_another_value = do_something_else的(RETURN_VALUE); < - 同步
writeData(return_another_value); < - 异步功能
VAR final_value = do_something_last(变量2); < - 同步功能
//可能有异步同步调用后再次调用
writeDataAgain(return_another_value); < - 异步功能

澄清

我认为是因为其中的一些功能,同步将需要异步之后被解雇,我需要让他们为了保持序列直,像这样无极意识到:


  

同步功能所做的承诺,认识到


  do_something =功能(输入){
  VAR递延= Q.defer();
  //分配变量,做其他的东西同步
  deferred.resolve(_output_result_);
  返回deferred.promise;
}
do_something_else的=功能(输入){
  VAR递延= Q.defer();
  //分配变量,做其他的东西同步
  deferred.resolve(_output_result_);
  返回deferred.promise;
}
do_something_last =功能(输入){
  VAR递延= Q.defer();
  //分配变量,做其他的东西同步
  deferred.resolve(完成工作流');
  返回deferred.promise;
}

这将使我做到这一点:

  do_something(变量)
。然后(do_something_else的)LT; - 这些都需要writeData前执行
。然后(writeData)LT; - 一个异步节点FS调用WriteFile的
。然后(do_something_last)LT; - 我需要这在writeDate发生后,
.done();

反馈我读过之后,我猜好像我真的问的是:


  

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



解决方案

  

只是做这个代替,并保持有序,像这样:

  writeData(return_another_value);
VAR final_value = do_something_last(变量2);


嗯,这是行不通的,因为 do_something_last writeData(...)承诺后不叫是的解决的。创建并返回后,承诺它会刚开始的权利。所以,如果你关心这个特定的顺序,并希望等到数据被写入,那么你的需求的使用然后有一个回调:

  VAR final_promise = writeData(return_another_value)。然后(功能(writeResult){
    返回do_something_last(变量2);
});


的一般规则是:


  • 请同步功能同步 - 无需承诺

  • 请所有异步函数总是返回一个承诺

  • 使用在尽可能低的水平 promisification
  • 仅deferreds

您可以只放在一个然后同步功能,无承诺返回值(甚至抛出的异常)工作,他们的罚款。
所以,当你的可以的写序列,例如

  Q(test1.txt的')
。然后(do_something)
。然后(do_something_else的)
。然后(writeData)
。然后(do_something_last.bind(空'的test2.txt'))
.done();

它看起来相当奇怪。如果你不打算让 do_something ■在不久的将来,异步出于某种原因,它往往是简单的写入和读取

  writeData(do_something_else的(do_something('test1.txt的')))。然后(函数(){
    返回do_something_last('的test2.txt');
})()完成。

诚然,它有时更具吸引力写

  somePromise()
。然后(doSomethingSynchronous)
。然后(doSomethingAsynchronous)

  somePromise
。然后(功能(RES){返回doSomethingAsynchronous(doSomethingSynchronous(RES));})

即使它们的功能相同。选择你喜欢的更好,这是比较一致的风格。

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

Context

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:

sync function

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

and need the above to take place before this function:

sync function

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

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

async function

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

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

sync 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

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:

sync functions made promise aware

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;
}

this would allow me to do this:

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

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:

  • 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

You can just place synchronous functions in a then chain, non-promise return values (or even thrown exceptions) work fine in them. So while you can write your sequence like

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

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)

than

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.

这篇关于当要使用承诺延期功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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