Open vaakian opened 2 years ago
Promise.all仅当所有promise都被resolve后触发then,结果得到结果数组。 该数组与传入的promise顺序一致,不管谁先被resolve。 否则catch收到第一个出现错误的promise
let p1 = new Promise((resolve) => {
setTimeout(() => resolve(1), 500)
})
let p2 = new Promise((resolve) => {
setTimeout(() => resolve(2), 100)
})
let p3 = Promise.resolve(3)
Promise.all([p1, p3, p2]).then((result) => {
console.log(result)
}).catch((error) => {
console.log(error)
})
// [1, 3, 2]
Promise.race捕获最先被resolve的promise
具体可以通过Promise.race实现 第一个版本,能够正常捕获错误。
function fetch() {
return new Promise((resolve) => {
setTimeout(() => {
resolve(100);
}, 200);
});
}
function counter(timeout) {
return new Promise((resolve, reject) => {
setTimeout(() => reject('http request timeout'), timeout);
})
}
Promise.race([fetch(), counter(100)]).then(data => {
console.log(data);
}).catch(err => {
console.log(err);
})
但这里错误捕获后,fetch并不会被中断,所以会继续请求下去,只是不会再被程序处理。
所以在counter执行后,应该取消fetch请求。
let controller = new AbortController();
let signal = controller.signal;
function someHttpRequest(signal) {
return fetch('https://github.com', {signal});
}
function counter(timeout, controller) {
return new Promise((resolve, reject) => {
setTimeout(() => {reject('http request timeout'); controller.abort();}, timeout);
})
}
Promise.race([someHttpRequest(signal), counter(10, controller)]).then(data => {
console.log(data);
}).catch(err => {
console.log(err);
})
当然实现超时有更简单的方法,这里只是一个应用。如:
function someHttpRequest(url, timeout, config = {}) {
let controller = new AbortController();
let signal = controller.signal;
return new Promise((resolve, reject) => {
setTimeout(() => {
controller.abort();
reject(new Error('request timeout'));
}, timeout);
resolve(fetch(url, { ...config, signal }));
})
}
someHttpRequest('https://github.com', 10)
.then(data => console.log(data))
.catch(err => console.log(err));
Promise.all是并行,实现Promise.run串行?
const serialPromises = function (promises = []) {
return new Promise((resolve, reject) => {
let result = []
function inner(i) {
if (i >= promises.length) {
// promise全部执行完毕,返回结果
resolve(result)
} else {
promises[i]().then(data => {
result.push(data)
inner(i + 1)
// 一旦遇到错误,就直接reject
}).catch(err => reject(err))
}
}
inner(0)
})
}
测试
function p1() {
console.log('p1')
return new Promise((resolve) => {
setTimeout(() => resolve('1'), 2000)
})
}
function p2() {
console.log('p2')
return Promise.reject('2')
}
function p3() {
console.log('p3')
return Promise.resolve('3')
}
serialPromises([p1, p2, p3])
.then(resultArr => {
console.log(resultArr)
})
.catch(err => console.log(err))
Promise中resolve一个Promise
从例子中,显然能发现如果Resolve/Reject传过来的同样是Promise,那么继续接管当前Promise,直到Promise完成再将数据交给第一个Then。