承诺的动态顺序执行

时间:2018-04-29 17:43:49

标签: javascript angular ionic-framework

我需要按顺序运行动态数量的承诺。 我理解我如何能够按顺序执行承诺,但我不会成功地通过一系列可能不同的承诺来实现它。

我发现这是一种静态How to resolve promises one after another?

的方法



function waitFor(timeout) {
	return new Promise(function(resolve, reject) {
		setTimeout(function() {
			resolve(`Finished waiting ${timeout} milliseconds`);
		}, timeout);
	});
}

waitFor(1000).then(function(result) {
	$('#result').append(result+' @ '+(new Date().getSeconds())+'<br>');
    return waitFor(2000);
}).then(function(result) {
    $('#result').append(result+' @ '+(new Date().getSeconds())+'<br>');
    return waitFor(3000);
}).then(function(result) {
	$('#result').append(result+' @ '+(new Date().getSeconds())+'<br>');
});
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div id="result"></div>
&#13;
&#13;
&#13;

我想做同样的事情但不是3个嵌套的承诺,我想要任何我想要的号码。 你能帮助我吗 ?

非常感谢!!

4 个答案:

答案 0 :(得分:1)

创建一个seprate函数来处理迭代次数

function waitFor(timeout) {
    return new Promise(function(resolve, reject) {
        setTimeout(function() {
            resolve(`Finished waiting ${timeout} milliseconds`);
        }, timeout);
    });
}
function resultHandler(result) {
    $('#result').append(result+' @ '+(new Date().getSeconds())+'<br>');
    return waitFor(2000);
}
function repeat(promise,num){
    if(num>0)
    repeat(promise.then(resultHandler),num-1);
}

repeat(waitFor(1000),2)

答案 1 :(得分:1)

Promise有三种基本方法可以完成这项任务。

  1. .reduce()模式。
  2. function waitFor(timeout) {
    	return new Promise(function(resolve, reject) {
    		setTimeout(function() {
    			resolve(`Finished waiting ${timeout} milliseconds`);
    		}, timeout);
    	});
    }
    
    var timeouts = [1000, 2000, 2000, 3000, 1000],
        sequence = tos => tos.reduce((p,c) => p.then(rp => waitFor(c))
                                               .then(rc => console.log(`${rc} @ ${new Date().getSeconds()}`)), Promise.resolve());
    
    sequence(timeouts);

    1. 递归模式。
    2. function waitFor(timeout) {
      	return new Promise(function(resolve, reject) {
      		setTimeout(function() {
      			resolve(`Finished waiting ${timeout} milliseconds`);
      		}, timeout);
      	});
      }
      
      var timeouts = [1000, 2000, 2000, 3000, 1000],
          sequence = ([to,...tos]) => to !== void 0 && waitFor(to).then(v => (console.log(`${v} @ ${new Date().getSeconds()}`), sequence(tos)));
      
      sequence(timeouts);

      1. 从左侧模式扫描。
      2. scanl模式会一个接一个地对承诺进行排序,但一旦完成,您也可以访问临时承诺解决方案。在某些情况下,这可能很有用。如果您要懒惰地构造异步树结构(仅在需要时从节点分支),您需要访问先前的承诺解析。

        为了在JS中实现scanl功能,首先我们必须实现它。

        var scanl = (xs, f, acc) => xs.map((a => e => a = f(a,e))(acc))
        

        我们向scanl提供xs,这是此特定示例中的超时数组f,它是一个回调函数,它接受acc(累加器)和{ {1}}(当前项)并返回新的累加器。累加器值(临时承诺分辨率)映射在超时数组上,以便在需要时访问。

        e
        function waitFor(timeout) {
        	return new Promise(function(resolve, reject) {
        		setTimeout(function() {
        			resolve(`finished waiting ${timeout} milliseconds`);
        		}, timeout);
        	});
        }
        
        var timeouts = [1000, 2000, 2000, 3000, 1000],
            scanl    = (xs, f, acc) => xs.map((a => e => a = f(a,e))(acc)),
            proms    = scanl(timeouts,                                             // input array
                             (a,t,r) => a.then(v => (r = v, waitFor(t)))           // callback function
                                         .then(v => (console.log(`${r} and ${v}`),
                                                     `${r} and ${v}`)),
                             Promise.resolve(`Started with 0`));                   // accumulator initial value
        
        // Accessing the previous sub sequential resolutions
        Promise.all(proms)
               .then(vs => vs.forEach(v => console.log(v)));

答案 2 :(得分:0)

忘记我评论过(当你将Promise转换为Observable或在数组中包含promise时,执行Promise)。您可以使用“递归”功能

  foolPromise(index: number, interval: number) {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve({ id: index, data: new Date().getTime() % 100000 });
      }, interval);
    })
  }
  intervals: number[] = [1000, 50, 500];
  recursive(req: any, index: number) {
    req.then(res => {
      console.log(res);
      index++;
      if (index < this.intervals.length)
        this.recursive(this.foolPromise(index, this.intervals[index]), index);
    })
  }

  ngOnInit() {
    this.recursive(this.foolPromise(0, this.intervals[0]), 0)
  }

答案 3 :(得分:-1)

如果您不关心序列化,可以使用Promise.all https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all

wc -l

或者,您可以使用异步功能:

Promise.all([promise1, promise2, promise3]).then(function(values) {
  // do something with values
}).catch(function(err) {
  // error called on first failed promise
});