Step-By-Step
Step-By-Step copied to clipboard
实现 Promise.race 方法
差不多的把,和promise.all,只不过catch的话就要用setTime或者请求来触发reject
哪个promise先被处理完,就返回哪个的结果,可以是reject也可以是resolve
Promise.race = function (promises) {
return new Promise(((resolve, reject) => {
for (let i = 0; i < promises.length; i++) {
Promise.resolve(promises[i]).then((data) => {
resolve(data);
return;
}, err=>reject(err));
}
}
));
}
测试代码
let promise1 = new Promise((resolve, reject) => {
setTimeout(resolve, 200, '100');
})
let promise2 = new Promise((resolve, reject) => {
setTimeout(resolve, 100, '200');
})
let promise3 = new Promise((resolve, reject) => {
setTimeout(resolve, 200, '300');
});
const race = function (iterable) { return new Promise(function (resolve, reject) { for (const i in iterable) { const v = iterable[i] if (typeof v === 'object' && typeof v.then === 'function') { v.then(resolve, reject) } else { resolve(v) } } }) }
const p1 = new Promise(function (resolve) { setTimeout(resolve, 200, 1) }) const p2 = new Promise(function (resolve) { setTimeout(resolve, 100, 2) }) race([p1, p2]).then(function (res) { console.log(res) }) // 2
Promise.race实现
Promise.race方法和Promise.all方法差不多,只是Promise.all需要等待所有的请求都完成,而Promise.race只要有一个请求完成就可以。 具体实现如下:
Promise.race = function(promises) {
return new Promise(function(resolve, reject) {
for (let i = 0; i < promises.length; i++) {
Promise.resolve(promises[i]).then(function(value) {
return resolve(value)
}, function(reason) {
return reject(reason)
})
}
})
}
Promise.race = function (promises) {
if (!(promises instanceof Array))
return reject("arguments must be an array");
return new Promise((resolve, reject) => {
if (promises.length === 0) {
return;
} else {
for (let i = 0; i < promises.length; i++) {
Promise.resolve(promises[i]).then(data => {
return resolve(data);
}, err => {
return reject(err);
});
}
}
});
}
1.promise.race的实现
Promise.race = function(promiseArray) {
return new Promise((res, rej) => {
for (let i = 0; i < promiseArray.length; i++) {
Promise.resolve(promiseArray[i]).then(
function(value) {
//成功
return res(value);
},
function(error) {
//失败
return rej(error);
}
);
}
});
};
2.测试
let promise1 = new Promise((resolve, reject) => {
setTimeout(resolve, 200, "promise1");
});
let promise2 = new Promise((resolve, reject) => {
setTimeout(resolve, 1000, "promise2");
});
let promise3 = new Promise((res, rej) => {
setTimeout(rej, 60, "fail");
});
Promise.race([promise1, promise2, promise3]).then(val => {
console.log(val);
});
概念
Promise.race(iterable),当iterable参数里的任意一个子promise被成功或失败后,父promise马上也会用子promise的成功返回值或失败详情作为参数调用父promise绑定的相应句柄,并返回该promise对象
应用场景
- 有些时候,多个异步任务是为了容错。比如,同时向两个URL读取用户的个人信息,只需要获得先返回的结果即可
代码实现
Promise.race = function (promises) {
if (!Array.isArray(promises)) {
throw new TypeError('You must pass array')
}
return Promise(function (resolve, reject) {
function resolver(value) {
resolve(value)
}
function rejecter(reason) {
reject(reason)
}
for (var i = 0; i < promises.length; i++) {
promises[i].then(resolver, rejecter)
}
})
}
测试
var p1 = new Promise(function (resolve, reject) {
setTimeout(resolve, 500, '2018');
});
var p2 = new Promise(function (resolve, reject) {
setTimeout(resolve, 600, '2019');
});
Promise.race([p1, p2]).then(function (result) {
console.log(result); // '2018' 因为2018更快
});
Promise.race 的实现
这边先说下Promise.race的几个注意点
- Promise.race 用于将多个Promise对象包装成一个新的promise对象
- 其状态由这多个promise对象中状态最先变为fullfilled 或rejected 的promise 对象决定
- p的终值或拒因由最先变更状态的promise对象决定
Promise.race = arr => {
return new Promise((resolve, reject) => {
function myresolve(result) {
resolve(result)
}
function myreject (error) {
reject(error)
}
for (let i = 0;i <arr.length; i++ ) {
arr[i].then(myresolve, myreject)
}
})
}
概念 Promise.all 返回的是传入的promise list 中每一单项调用之后的结果 Promise.race 返回的是传入的promise list 中最先返回的单项的调用结果 无论成功与否
实现
Promise.race= function(promises){
if(!Array.isArray(promises)){
throw new Error('not a array')
}
return new Promise(function(resolve,reject){
fucntion resolver(value){
reslove(value)
}
function rejecter(value){
reject(value)
}
for(var i=0;i<promises.length;i++){
promises[i].then(resolver,rejecter)
}
})
}
测试
let p1 = new Promise(function(resolve,reject){
setTimeout(function(){
resolve('success')
},1000)
})
let p2 = new Promise(function(resolve,reject){
setTimeout(function(){
resolve('faild')
},500)
})
Promise.race([p1,p2]).then(result=>{
console.log(result) // faild faild耗时短
})
在实现 Promise.race
方法之前,我们首先要知道 Promise.race
的功能和特点,因为在清楚了 Promise.race
功能和特点的情况下,我们才能进一步去写实现。
Promise.race 功能
Promise.race(iterable)
返回一个 promise,一旦 iterable
中的一个 promise
状态是 fulfilled
/ rejected
,那么 Promise.race
返回的 promise
状态是 fulfilled
/ rejected
.
let p = Promise.race([p1, p2, p3]);
只要p1、p2、p3之中有一个实例率先改变状态,p的状态就跟着改变。那个率先改变的 Promise
实例的返回值,就传递给 p 的回调函数。
Promise.race 的特点
Promise.race 的返回值是一个 promise 实例
- 如果传入的参数为空的可迭代对象,那么
Promise.race
返回的promise
永远是pending
态 - 如果传入的参数中不包含任何
promise
,Promise.race
会返回一个处理中(pending)的promise
- 如果
iterable
包含一个或多个非promise
值或已经解决的promise,则Promise.race
将解析为iterable
中找到的第一个值。
Promise.race 的实现
Promise.race = function (promises) {
//promises传入的是可迭代对象(省略参数合法性判断)
promises = Array.from(promises);//将可迭代对象转换为数组
return new Promise((resolve, reject) => {
if (promises.length === 0) {
//空的可迭代对象;
//用于在pending态
} else {
for (let i = 0; i < promises.length; i++) {
Promise.resolve(promises[i]).then((data) => {
resolve(data);
}).catch((reason) => {
reject(reason);
})
}
}
});
}
Promise.race = function(promises) {
return new Promise(function(resolve, reject) {
if (!promises || typeof promises[Symbol.iterator] !== 'function') {
reject(TypeError());
}
for (let i = 0; i < promises.length; i++) {
Promise.resolve(promises[i]).then(function(data) {
resolve(data);
}, function(error) {
reject(error);
});
}
});
}
ღ( ´・ᴗ・` )比心
const createPromise = (method) => {
const promise = new Promise((resolve, reject) => {
method(resolve, reject)
})
return promise
}
const race = (...tasks) => {
tasks = tasks.flat()
let tasksLength = tasks.length
return createPromise((resolve, reject) => {
let taskObj = {}
Object.defineProperty(taskObj, '嘤嘤嘤', {
set: ({
type,
data
}) => {
if (type === 'resolve') {
resolve(data)
} else {
reject(data)
}
}
})
for (let step = 0, len = tasksLength; step < len; ++step) {
const task = Promise.resolve(tasks[step])
task.then(taskRes => {
taskObj['嘤嘤嘤'] = {
type: 'resolve',
data: taskRes
}
}).catch(tashRej => {
taskObj['嘤嘤嘤'] = {
type: 'reject',
data: tashRej
}
})
}
})
}
race([p1, p2, p3]).then(res => {
console.log(res)
}).catch(err => {
console.log(err)
})
Promise.race([p1, p2, p3]).then(res => {
console.log(res)
}).catch(err => {
console.log(err)
})
Promise.nanlanRace = function (promises) {
return new Promise(function (resolve, reject) {
if (!(promises instanceof Array)) {
return reject("params muse be Arrary");
} else if (promises.length === 0) {
//空的可迭代对象;
//用于在pending态
} else {
for (let i = 0; i < promises.length; i++) {
Promise.resolve(promises[i]).then(res => {
resolve(res);
}, (err) => {
reject(err)
})
}
}
})
}
var p1 = new Promise(function (resolve, reject) {
setTimeout(resolve, 500, "one");
});
var p2 = new Promise(function (resolve, reject) {
setTimeout(resolve, 100, "two");
});
Promise.nanlanRace([p1, p2]).then(function (value) {
console.log(value); // "two"
// 两个都完成,但 p2 更快
});