我正在使用 Q Node 库来实现 Promises,我认为这个问题也适用于 Bluebird 库。
上下文
我需要对我自己的自定义函数和 Node.js fs
风格的异步函数进行一些函数调用。
如果我要调用这样的函数:
sync function
do_something = function (input) {
// assign variables, do other sync stuff
}
并且需要在此函数之前
执行上述操作:
sync function
do_something_else = function (input) {
// assign variable, do other sync stuff
}
和then
需要调用类似于以下内容的 native Node 函数:
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);
}
和最后
需要在此函数之前
进行上述操作:
sync function
do_something_last = function (input) {
// assign variable, do other sync stuff
}
问题
这里要做的“正确”的事情是让我的所有函数“延迟”或 promise 感知,以便我可以确保它们按顺序或以正确的顺序调用? 像这样:
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 以便保持顺序正确,如下所示:
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;
}
这将允许我这样做:
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();
在阅读完反馈后,我想我真正要问的是:
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_last
在 writeData(…)
promise 解决后不会被调用。解决。它会在 promise 创建并返回后立即开始。因此,如果您关心该特定顺序并希望等到数据写入,那么您需要将then
与回调一起使用:
var final_promise = writeData(return_another_value).then(function(writeResult) {
return do_something_last(variable2);
});
一般规则是:
- 使同步函数同步 - 不需要 Promise
- 使所有异步函数始终返回 Promise
- 仅在 promisification 的尽可能最低级别使用延迟
您可以将同步函数放在then
链中,非 promise 返回值(甚至抛出异常)在其中可以正常工作。
因此,虽然您可以编写序列,例如
Q('test1.txt')
.then(do_something)
.then(do_something_else)
.then(writeData)
.then(do_something_last.bind(null, 'test2.txt'))
.done();
看起来很奇怪。如果由于某种原因您不打算在不久的将来使 do_something
变得异步,那么编写和读取通常会更简单
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)); })
即使它们功能相同。选择您更喜欢且更一致的风格。
关于javascript - 何时使用 Promises 延迟函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28993673/