Javascript 如何使用变量函数调用创建顺序promise循环

Javascript 如何使用变量函数调用创建顺序promise循环,javascript,node.js,loops,promise,Javascript,Node.js,Loops,Promise,我需要以某种方式循环传递给\u start的工作数组,然后 对于数组中的每个项,我需要以某种方式调用同名的对应函数 我无法控制work数组中的项数或项数,我知道总会有相应的函数 我不想同时调用所有函数,当第一个函数在3秒钟后解析时,我想调用第二个函数,当第二个函数在3秒钟后解析时,我想调用第三个函数。第三个函数在3秒钟后解析后,我想调用_done() 在本例中,每个函数需要3秒钟才能完成\u done不会被调用9秒钟 function _start(data){ // Insert so

我需要以某种方式循环传递给
\u start
工作
数组,然后 对于数组中的每个项,我需要以某种方式调用同名的对应函数

我无法控制
work
数组中的项数或项数,我知道总会有相应的函数

我不想同时调用所有函数,当第一个函数在3秒钟后解析时,我想调用第二个函数,当第二个函数在3秒钟后解析时,我想调用第三个函数。第三个函数在3秒钟后解析后,我想调用_done()

在本例中,每个函数需要3秒钟才能完成
\u done
不会被调用9秒钟

function _start(data){
    // Insert some kinda native magic loop
}


function _one(){
    return new Promise((resolve, reject) => {
        setTimeout(function(){ 
            resolve(1); 
        }, 3000);
    })
};


function _two(){
    return new Promise((resolve, reject) => {
        setTimeout(function(){ 
            resolve(2); 
        }, 3000);
    })
};

function _done(){
    console.log('All done in 9 seconds)
}


(function(){
    var work = ['_one', '_two', '_two'];
    _start(work);
})();

使用
承诺
然后

_one().then((responseOne) => {
    return _two();
}).then((responseTwo) => {
    // _one & _two are done
});
尝试使用以下方法:

_one().then((firstResponse) {
      return_two();
}) .then((secondResponse) => {
 *second and first respone are already done*

});

给定数组指示的顺序,您可以使用将承诺聚合成一个链

const _start = (...actions) => {
  return actions.reduce((chain, action) => {
    const func = this[action];
    return chain.then(() => func());
  }, Promise.resolve());
}
...
_start('_one', '_two', '_three').then(() => console.log('All done'));

参见-该示例将额外的<代码>然后< /代码>添加到链中,以输出来自承诺的任何结果(可能超出了这个问题的范围,但如果需要返回数据,则可能需要考虑的一些事情)。 更新

可以看出您打算从声明函数的不同上下文调用
\u start
,这很好,但您需要确保事先设置了正确的上下文,即

const self = this;
(function() {
  _start.bind(self)('_one', '_two', '_two');
})();

一个函数,创建一个休眠的承诺:

const sleep = n => () => new Promise(resolve => setTimeout(resolve, n));
在某些输入承诺后休眠的函数:

const sleepAfter = n => p => p.then(sleep(n));
一种将一系列承诺串联起来的函数,由函数表示:

const chain = (...promises) => promises.reduce((ret, promise) => ret.then(promise), 
  Promise.resolve());
运行一系列产生承诺的函数,并在这两者之间穿插:

const _start = promises => chain(promises.map(sleepAfter(3000)));
现在只需:

_start(_one, _two, _three).then(_done);

如果我知道工作数组中项目的顺序和数量,这将非常有用。如果我不知道,我如何使其工作?如果我知道工作数组中项目的顺序和数量,这将非常有用。如果我不知道,我如何使其工作?在使用案例中,我不知道
工作
数组中项目的顺序或数量。我知道他们会有一个同名的对应函数,环境是最新的node.js安装嘿,James,看起来不错,我给每个函数添加的延迟只是为了模拟一些异步调用,我不知道需要多长时间才能完成return@Bill啊,好的,我认为这是一个特定的规则,即只在上一次完成X秒后运行下一个动作。这很好,您可以忽略这一部分,目前唯一的缺点是从操作中获得结果(即
resolve(1)
等)。你需要从这些承诺中找回价值吗?如果是这样的话,我也需要更新解决方案来聚合这些内容。@torazaburo yeah是在玩弄这个想法,或者是在链中发出了第一个承诺……但你认为是对的,只是保持代码的一致性。@Bill去掉了延迟代码,如果它不是必需的,那么它只是污染了解决方案。使用Promise.all会同时调用所有函数吗?或者在调用“工作”数组中的下一个之前,它会等待第一个数组完成吗?挑战的一部分是承诺是字符串数组,而不是实际的引用。有两种方法,一种是在
链中映射
(假设上下文是相同的,看起来是一样的),另一种是在外部映射,即
(开始([…])。映射(a=>this[a])
FWIW
ret.then(promise())
应该是
ret.then(promise)
否则,您的所有承诺都将同时开始,而且不符合顺序。您的
\u start
/
sleep
funcs上也缺少一个右括号。@James感谢您的提示,拼写错误已修复。至于以字符串形式提供函数,我并不认为这是解决这个问题的规范的一部分,因为通过字符串名称引用JS值在最好的情况下是棘手的,在最坏的情况下是不可能的。