-
Notifications
You must be signed in to change notification settings - Fork 3.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
第 89 题:设计并实现 Promise.race() #140
Labels
Comments
Promise._race = promises => new Promise((resolve, reject) => {
promises.forEach(promise => {
promise.then(resolve, reject)
})
}) |
Promise.myrace = function(iterator) {
return new Promise ((resolve,reject) => {
try {
let it = iterator[Symbol.iterator]();
while(true) {
let res = it.next();
console.log(res);
if(res.done) break;
if(res.value instanceof Promise) {
res.value.then(resolve,reject);
} else {
resolve(res.value)
}
}
} catch (error) {
reject(error)
}
})
} |
基本和上面的例子差不多,不同点是每个传入值使用Promise.resolve转为Promise对象,兼容非Promise对象 const _race = (p)=>{
return new Promise((resolve, reject)=>{
p.forEach((item)=>{
Promise.resolve(item).then(resolve, reject)
})
})
} |
Promise.miniRace = function(promises) {
return new Promise((rs,rj)=>{
try {
// 检查输入值是否可迭代
iteratorCheck(promises)
const len = promises.length;
let promiseStatusChanged = false;
for (let i = 0; i < len; i++) {
if (promiseStatusChanged)
break;
// 使用 Promise.resolve 包装 thenable 和 非thenable 值
Promise.resolve(promises[i]).then(rs).catch(rj).finally(()=>{
promiseStatusChanged = true
}
)
}
} catch (e) {
rj(e)
}
}
)
}
function iteratorCheck(data) {
if (!data[Symbol.iterator] || typeof data[Symbol.iterator] !== 'function') {
const simpleType = typeof data;
let errMsg = simpleType
if (['number', 'boolean'].includes(simpleType) || data === null) {
errMsg += ` ${String(data)}`
}
throw new TypeError(`${errMsg} is not iterable (cannot read property Symbol(Symbol.iterator))`)
}
} |
const PromiseRace = (iterable)=>{
return new Promise((resolve, reject) => {
for (const p of iterable) {
Promise.resolve(p).then(resolve).catch(reject)
}
})
} |
Promice.race= function(PromiseArr){
let hasResolve = false
return new PromiceA((resolve,reject)=>{
PromiseArr.forEach(promiseItem=>{
promiseItem.then(res=>{
!hasResolve && resolve(res)
hasResolve = true
},(err)=>{
!hasResolve && reject(err)
})
})
})
} |
let p1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('success')
}, 100)
})
let p2 = new Promise((resolve, reject) => {
setTimeout(() => {
reject('failed')
}, 500)
})
/**
* 实现一个race
* @param {Array} array
*/
let race = function (array) {
return new Promise((resolve, reject) => {
let len = array.length;
while (len--) {
array[len].then(res => {
return resolve(res);
}).catch(err => {
return reject(err);
})
}
})
}
// 调用
race([p1, p2]).then(res => {
console.log(res);
}).catch(err => {
console.error(err);
}) |
Promise._race = function(Promises) { |
Promise.race = function(...list) {
return new Promise((resolve, reject) => {
for (let item of list) {
let p = item.then ? p : Promise.resolve(p)
// p.then(value => {
// resolve(value)
// }).catch(err => {
// reject(err)
// })
p.then(resolve, reject)
}
})
} |
|
resolve()前 没必要return 吧 |
function promiseRace(promises) {
return new Promise((res, rej) => {
promises.forEach(promise => promise.then(res).catch(rej));
})
} |
|
static race(arr) {
// 只要p1、p2、p3之中有一个实例率先改变状态,p的状态就跟着改变。
return new PromiseA((resolve, reject) => {
arr.forEach((item)=>{
// “状态的变更是单向的”
item.then(resolve, reject);
})
})
} |
有点像电路的并行,只要有一个开关打开的就可以接通了。 |
Promise.race = function(promises){
return new Promise((resolve, reject)=>{
for(let i of promises){
Promise.resolve(i).then(resolve, reject)
}
})
} |
function testRace() {
function getPromise(i, timeout = 0) {
const random = Math.random();
return new Promise((resolve, reject) => {
setTimeout(() => {
random > 0.5 ? reject(`reject: ${random} - ${i}`) : resolve(`resolve: ${random} - ${i}`)
}, timeout)
})
}
Promise.race2 = function (promises) {
return new Promise((resolve, reject) => {
for (let i = 0; i < promises.length; i++) {
// promises[i] 可能是普通值
Promise.resolve(promises[i]).then((data) => {
resolve(data);
}, (err) => {
reject(err)
});
}
});
}
const p1 = getPromise(1, 200);
const p2 = getPromise(2, 300);
const p3 = getPromise(3, 100);
Promise.race([p1, p2, p3])
.then((res) => {
console.log('res:', res)
})
.catch((err) => {
console.log('err:', err);
})
Promise.race2([p1, p2, p3])
.then((res) => {
console.log('res:', res)
})
.catch((err) => {
console.log('err:', err);
})
}
testRace(); Promise.race(iterable) 方法返回一个 promise,一旦迭代器中的某个promise解决或拒绝,返回的 promise就会解决或拒绝。 可以通过设置 getPromise 函数的第二个参数,验证race2 输出结果与 race是否一致 |
|
Tip:
const isIterable = (data, reject) => {
const type = typeof data;
if (!data[Symbol.iterator]) {
if (reject) {
reject(
new TypeError(
`${type} ${data} is not iterable (cannot read property Symbol(Symbol.iterator))`
)
);
} else {
throw new TypeError(
`${type} ${data} is not iterable (cannot read property Symbol(Symbol.iterator))`
);
}
}
};
Promise.myRace = function (promises) {
return new Promise((resolve, reject) => {
isIterable(promises, reject); // 判断是否是迭代对象
const promiseArray = [...promises];
promiseArray.forEach((pr) => {
if (!(pr instanceof Promise)) {
pr = Promise.resolve(pr);
}
pr.then(resolve, reject);
});
});
};
const promise1 = new Promise((resolve, reject) => {
setTimeout(resolve, 500, "one");
});
const promise2 = new Promise((resolve, reject) => {
setTimeout(reject, 100, "two");
});
Promise.myRace([promise1, promise2])
.then((value) => {
console.log("value", value);
// Both resolve, but promise2 is faster
})
.catch((err) => {
console.log("err", err);
}); |
Promise.race = function(values){
return new Promise((resolve,reject)=>{
for(let i = 0 ; i< values.length;i++){
Promise.resolve(values[i]).then(resolve,reject)
}
})
} |
Promise.race = function (proms) {
return new Promise((rs, rj) => {
proms.forEach(p => {
Promise.resolve(p).then(rs).catch(rj);
})
});
} |
|
Promise.myRace = (promises) => {
const _promises = Array.isArray(_promises) ? _promises : [promises];
return new Promise((resolve, reject) => {
_promises.forEach((promise) => {
Promise.resolve(promise).then(resolve, reject);
});
});
}; |
Promise.fakeRace = function (list) {
return new Promise((resolve, reject) => {
list.forEach((promise) => {
promise.then(resolve, reject);
});
});
};
function createPromise(i) {
return new Promise((resolve, reject) => {
const timer = setTimeout(() => {
// resolve(i);
reject(i);
clearTimeout(timer);
}, i * 100);
});
}
Promise.fakeRace([createPromise(1), createPromise(2)]).then(
(data) => console.log("fullfilled", data),
(e) => console.log("rejected", e)
); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
No description provided.
The text was updated successfully, but these errors were encountered: