2017-02-11 1893 views
0

我有一个函数foo(),其中包含一个可解析for循环的Promise。我想多次运行foo(),每次都给它不同的参数。然后,我想对所有这些结果做一些事情。将Promise.all()运行在for循环的结尾还是在foo()的所有Promise之后返回?或者它会说“这些foo()都不是诺言!”并嘲笑我?如何在for循环中创建Promise后使用Promise.all()

var foo = (x) => { 
    for (var i = 0; i < 100; i++) { 
     someOtherFunctionThatReturnsAPromise(x).then(returnSomething()); 
    } 
}; 

function nowDoEverything() { 
    return Promise.all([foo(1), foo(2), foo(3)]).then(doSomethingWithAllThoseReturnedValues()); 
} 

nowDoEverything(); 

foo()是否需要返回一个Promise?如果是这样,考虑到foo()中的Promise是在for循环内部生成的,我该怎么做呢?

https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise/all指出 “Promise.all(iterable)方法返回一个promise,当迭代参数中的所有promise都解决了,或者拒绝了第一个传递的promise的拒绝原因。

此视频https://www.youtube.com/watch?v=RRgAdi3gX-s真的很擅长解释基本的承诺,但我似乎试图做一些建筑师不打算/期望的事情。

回答

2

按承诺的数组,数组return,内.then()从功能省略()避免立即调用功能:您可以将每个承诺添加到一个数组,并使用Promise.all等待他们。使用传播元素foo()调用返回单个承诺数组.then()链接到Promise.all()

var foo = (x) => { 
    var arr = []; 
    for (var i = 0; i < 100; i++) { 
     arr.push(someOtherFunctionThatReturnsAPromise(x).then(returnSomething)); 
    } 
    return arr 
}; 

function nowDoEverything() { 
    return Promise.all([...foo(1), ...foo(2), ...foo(3)]) 
      .then(doSomethingWithAllThoseReturnedValues) 
} 

nowDoEverything() 
.catch(err => console.log(err)); 
+0

太好了,谢谢!省略号(... foo(1))是什么? –

+1

@GlenPierce'...'punctuator可以传播元素或rest元素,具体取决于用法,请参阅[ECMAScript文档中的SpreadElement是什么?它是否与MDN上的Spread运算符相同?](http://stackoverflow.com/questions/37151966/what-is-spreadelement-in-ecmascript-documentation-is-it-the-same-as-spread-oper) 。如果没有扩展元素,那么在数组中将会有三个或N次'foo'调用数组传递给'Promise.all()'中的'.then()'而不是单个数组。 'Promise.all([[1,2,3],[4,5,6]])。then(data => console.log(data)); Promise.all([... [1,2,3],... [4,5,6]])。然后(data => console.log(data))''。 – guest271314

1

是的,没错。这里是Promise.all()签名:

Promise.all<T>: (Iterable<Promise<T>): Promise<T[]> 

基本上,它接受承诺的迭代,并返回自己的承诺。

通过传递foo()的结果,foo()预计会返回一个Promise本身,否则它将无法工作。

+0

那么,它会立即解决''[undefined,undefined,undefined]'。 – Ryan

+0

@Ryan Right,这并不是很有帮助。 –

1

是的,foo()需要返回承诺。从foo

var foo = x => { 
    var results = []; 

    for (var i = 0; i < 100; i++) { 
     results.push(
      someOtherFunctionThatReturnsAPromise(x) 
       .then(returnSomething) 
     ); 
    } 

    return Promise.all(results); 
};