2017-02-11 1887 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); 
};