Open yygmind opened 5 years ago
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) { return new Promise((resolve, reject) => { Promises.forEach(p => p.then(resolve, reject)) }) }
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)
}
})
}
function promiseRace(promiseArr) {
return new Promise((resolve,reject) => {
for(let i = 0;i < promiseArr.length;i++) {
promiseArr[i].then(res => resolve(res),rej => reject(rej))
}
})
}
const pro1 = new Promise((res,rej) => {
setTimeout(() => {
res('我是1')
},1000)
})
const pro2 = new Promise((res,rej) => {
setTimeout(() => {
res('我是2')
},10000)
})
const pro3 = new Promise((res,rej) => {
setTimeout(() => {
res('我是3')
},300)
})
const race = promiseRace([pro1,pro2,pro3])
race.then(res => {
console.log(res)
})
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); })
resolve()前 没必要return 吧
function promiseRace(promises) {
return new Promise((res, rej) => {
promises.forEach(promise => promise.then(res).catch(rej));
})
}
Promise.protopype.race = (promises) => {
return new Promise((resolve, reject) => {
promises.forEach(promise => promise.then(resolve, reject))
});
}
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是否一致
Promise._race = function(iterator) {
return new Promise((resolve, reject) => {
for (let item of iterator) {
Promise.resolve(item).then((data) => {
resolve(data);
}).catch(err => {
reject(err);
});
}
});
}
Tip:
Promise.race(iterable) 方法返回一个 promise,一旦迭代器中的某个 promise 解决或拒绝,返回的 promise 就会解决或拒绝
判断函数参数是否是可迭代的(很多答案都忽略了)
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);
})
});
}
static race<T extends Iterable<any>>(args: T) { //约定T从属于Iterable类型
return new MyPromise((resolve, reject) => {
const promise = Array.from(args); //将args转化为数组类型
if (promise.length === 0){ //假设数组长度为0, 则永远处于pending状态
return
}
/**会执行所有resolve或者reject,
* 但是Promise内部状态只会变化一次(pending->fulfilled | pending->rejected)
* 所以只会保留第一次状态改变
*/
for (let i = 0; i < promise.length; i++) {
//用Promise.resolve包裹一层, 可以将非Promise对象转为Promise对象
MyPromise.resolve(promise[i]).then(data => {
resolve(data);
},reason => {
reject(reason)
})
}
})
}
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)
);