Javascript 函数返回对象数组时如何使用承诺

Javascript 函数返回对象数组时如何使用承诺,javascript,node.js,promise,bluebird,Javascript,Node.js,Promise,Bluebird,我有一个不使用承诺的复杂节点应用程序,但我意识到我有一个异步问题需要解决,承诺似乎是一种可能的方法。不过,我没有承诺方面的经验,我发现学习曲线很有挑战性 为了保持封装性和可测试性,应用程序的一部分和另一部分之间的主要接口是要执行的操作列表。这只是一个对象数组,其属性由调用函数用于执行操作。因此,第一个模块更抽象,只是指定要执行的一般操作,而调用模块是针对特定后端API执行操作的具体实现。为了保持封装性和可测试性,通用模块需要保持不知道特定模块 我遇到的问题是,现在需要由通用模块确定一系列异步步骤

我有一个不使用承诺的复杂节点应用程序,但我意识到我有一个异步问题需要解决,承诺似乎是一种可能的方法。不过,我没有承诺方面的经验,我发现学习曲线很有挑战性

为了保持封装性和可测试性,应用程序的一部分和另一部分之间的主要接口是要执行的操作列表。这只是一个对象数组,其属性由调用函数用于执行操作。因此,第一个模块更抽象,只是指定要执行的一般操作,而调用模块是针对特定后端API执行操作的具体实现。为了保持封装性和可测试性,通用模块需要保持不知道特定模块

我遇到的问题是,现在需要由通用模块确定一系列异步步骤,在特定模块中执行的早期操作完成之前,后面的步骤无法执行。但是,由于通用模块无法了解特定模块,因此无法自行执行操作。它所能做的就是将操作返回到特定模块

但是特定模块需要执行这些操作,然后执行通用模块确定的其他操作

这就是我被困的地方。我不知道如何将操作对象的列表以及它们的可编辑操作从通用模块返回到特定模块。我不知道这是因为我对蓝鸟缺乏了解,还是因为我试图做一些蓝鸟做不到的事情

一种方法似乎是向操作添加afterExecution属性,该属性是在操作完成后调用的后续函数。然而,这感觉很像土生土长的承诺,所以我不愿意走这条路

如果您仍然能够理解这个令人困惑的场景,那么我要问的是如何返回一个操作列表,这些操作在处理主操作对象之后也有一个“回调”函数要执行。这是蓝鸟能应付的吗


编辑: 经过一段时间的睡眠,我希望能说明我在追求什么。这里是我目前实现的精简版本

generic.js(无法了解specific.js):

specific.js

function createActions() {
    var actions = []

    var action1 = {command:'buy', qty:100, symbol:'S', price:3.50}
    var self = this
    action1.afterwards = function() {
       self.setStopAndTarget()
    }
    actions.push(action1)
    // add some more actions

    return actions
}
Promise.method(function checkForTrades() {
    var actions = generic.createActions()
    actions.forEach(function(a) {
        if( a.command === 'buy' ) {
            buyStock(a.symbol, a.qty, q.price).then(function(a) {
                if( a.afterwards ) {
                    a.afterwards()
                }
            })
        }
    })
})
因此,specific.jsgeneric.js中调用
createActions()
,以获取操作列表
actions
是一个JSON对象数组,但是,正如您所看到的,我还向
action
添加了一个函数,作为名为
的属性

specific.js然后处理
操作
。在
操作
完成后,我使用
承诺
检查属性是否存在。如果它存在,我调用它

我真正想做的是将
then()
编码在generic.js中,而不是specific.js,这样我就不必在
操作之后创建
属性。但我不知道该怎么做

我所做的一切都是可行的,但我非常确定Promises可以做到这一点,而无需在
操作中添加

另外,如果返回一系列操作,我想知道如何推迟
then()
操作,直到所有操作完成。我很确定这只是使用
承诺的问题。所有的
,但是看看语法会很有帮助


谢谢

我不确定我是否理解你的问题,但这里有一些想法

如果您告诉我在进入下一步之前需要同步一组响应,您可以使用或来进行同步

它们之间的区别就在于你传递论点的方式
Promise.all
接受一个表参数数组,而
Promise.join
接受一个表参数列表

两者的工作方式相同:只有在所有输入承诺都得到解决时,结果承诺才会得到解决。如果其中任何一项被拒绝,由此产生的承诺也将被拒绝


因此,如果你有一系列异步进程,你所要做的就是为每个进程创建一个承诺,然后将这些承诺传递给
promise.all

我不确定我是否理解了你的问题,但这里有一些想法

如果您告诉我在进入下一步之前需要同步一组响应,您可以使用或来进行同步

它们之间的区别就在于你传递论点的方式
Promise.all
接受一个表参数数组,而
Promise.join
接受一个表参数列表

两者的工作方式相同:只有在所有输入承诺都得到解决时,结果承诺才会得到解决。如果其中任何一项被拒绝,由此产生的承诺也将被拒绝


因此,如果您有一系列异步进程,那么您所要做的就是为每个进程创建一个承诺,然后将这些承诺传递给
promise。所有

有几种模式可能与此相关,具体取决于您试图完成的任务的细节

也许最有希望的是一种使用承诺实现的类似于共同例程的方法(当使用承诺时,请忘记“回调”一词)

在这种方法中,泛型模块将调用特定模块中的函数,该函数将在完成时返回一个承诺。然后,泛型模块挂起从特定模块返回的承诺的以下执行步骤。这里有一个非常基本的实现
function generic() {
  var specifics = [specific1, specific2, specific3];
  var promise = Promise.resolve();
  for (var i = 0; i < specifics.length; i++) {
    promise = promise.then(specifics[i]);
  }
  return promise;
}

function specific1() {
  return specific1_async_thing() . then(specific2_async_thing);
}
async function generic() {
  var specifics = [specific1, specific2, specific3];
  for (var i = 0; i < specifics.length; i++) {
    await specifics[i];
  }
}