Ale*_*nik 6 javascript es6-promise
我在这里阅读这篇文章,它讲述了如何使用reduce with promises,最后显示以下代码片段:
const tasks = getTaskArray();
return tasks.reduce((promiseChain, currentTask) => {
return promiseChain.then(chainResults =>
currentTask.then(currentResult =>
[ ...chainResults, currentResult ]
)
);
}, Promise.resolve([])).then(arrayOfResults => {
// Do something with all results
});
Run Code Online (Sandbox Code Playgroud)
所以在不改变太多代码的情况下,我做了以下演示:
const tasks = [ fetch('https://jsonplaceholder.typicode.com/todos/1') ,
fetch('https://jsonplaceholder.typicode.com/todos/2') ,
fetch('https://jsonplaceholder.typicode.com/todos/3') ];
tasks.reduce((promiseChain, currentTask) => {
console.log(promiseChain);
return promiseChain.then(chainResults => {
return currentTask.then(currentResult =>
[ ...chainResults, currentResult ]
)
});
}, Promise.resolve([])).then(arrayOfResults => {
// Do something with all results
console.log(arrayOfResults);
});
Run Code Online (Sandbox Code Playgroud)
但我仍然不明白,因为reduce简单地只是一个forEach循环而内部减少我们依赖于一个返回的promise,reduce函数不会仅仅循环遍历数组中的所有元素(在此case一个promises数组),没有then()触发?
小智 1
Ok, back from reading the article with a more complete answer. This tactic is for async tasks that rely on one another, but aren't always the same. If they were a fixed structure you would do (from the example):
return task1.then(result1 =>
task2.then(result2 =>
task3.then(result3 =>
[ result1, result2, result3 ]
)
)
).then(arrayOfResults => {
// Do something with all results
});
Run Code Online (Sandbox Code Playgroud)
Think of this in terms of doing maybe database work.
return dbOrm.task1.create()
.then(newRecord =>
// task 2 requires the id from the new record to operate
dbOrm.task2.create({task1_id: newRecord.id})
.then(result2 =>
// some other async that relies on result2
task3(result2).then(result3 =>
[ result1, result2, result3 ]
)
)
).then(arrayOfResults => {
// Do something with all results
});
Run Code Online (Sandbox Code Playgroud)
This is a fixed set of dependencies, they rely on each other to operate and you need the results of all of them to continue.
The example you linked is meant for that kind of serial execution but in a situation with non-fixed dependencies. Reduce is being used to synchronously constructing a chain of async actions that can then resolve on their own, and since the reduce function is returning a resolved promise you can chain another function off the end of it to handle the completed chain.
Reduce is more than a forEach loop even though they both use iteration to move over an array. Reduce also passes the returned result of the previous iteration to the next iteration. You are 'Reducing' your group of tasks down to one completed task; forEach doesn't act to change the array it is operating on (and Map, another iterating array function, returns a modified new array from the old).
so using the example code:
const tasks = getTaskArray();
return tasks.reduce((promiseChain, currentTask) => {
return promiseChain.then(chainResults =>
currentTask.then(currentResult =>
[ ...chainResults, currentResult ]
)
);
}, Promise.resolve([])).then(arrayOfResults => {
// Do something with all results
});
Run Code Online (Sandbox Code Playgroud)
给定 2 次迭代,你会得到类似的结果:
// 1
Promise.resolve([])
.then(chainResults => task1().then(task1Result => ([ ...chainResults, task1Result])
// 2
Promise.resolve([])
.then(chainResults => task1().then(task1Result => ([ ...chainResults, task1Result])
.then(chainResults => task2().then(task2Result => ([ ...chainResults, task2Result])
// the then after the reduce
Promise.resolve([])
.then(chainResults => task1().then(task1Result => ([ ...chainResults, task1Result])
.then(chainResults => task2().then(task2Result => ([ ...chainResults, task2Result])
.then(arrayOfResults => //do Something)
.catch(//because you should handle errors)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
145 次 |
| 最近记录: |