我已经为Chrome的Promise对象编写了这个“多填充”,并且我对实现有一些关注;
promise[method]工作方式。以下是扩展方法的工作原理:
var resolvedArray = Promise.resolve([1, 2, 3]);
resolvedArray.spread(function(a, b, c) {
console.log(a === 1); // true
console.log(b === 2); // true
console.log(c === 3); // true
});
var resolvedOther = Promise.resolve("Hello");
resolvedOther.spread(function(value) {
console.log(value === "Hello"); // true
});
var rejectedArray = Promise.reject([1, 2, 3]);
rejectedArray.spread(undefined, function(a, b, c) {
console.log(a === 1); // true
console.log(b === 2); // true
console.log(c === 3); // true
});
var rejectedObject = Promise.reject("Hello");
rejectedObject.spread(undefined, function(value) {
console.log(value === "Hello"); // true
});以下是我的实现:
Promise.prototype.spread = function() {
var promise = this;
var spread = function(promise, method, callback) {
return promise[method](function(previousValue) {
if (previousValue instanceof Array) {
return callback.apply(undefined, previousValue);
} else {
return callback.call(undefined, previousValue);
}
});
};
if (arguments.length >= 1 && arguments[0] !== undefined) {
promise = spread(promise, 'then', arguments[0]);
}
if (arguments.length >= 2 && arguments[1] !== undefined) {
promise = spread(promise, 'catch', arguments[1]);
}
return promise;
};发布于 2016-03-23 00:25:46
您的实现是使用.then(a, b)并将其映射到.then(a).catch(b),这与此不完全相同。在您的实现中,a中拒绝的承诺的异常或返回将击中.catch(b),但在.then(a, b)中,它不会击中b,因此我认为在某些情况下,.spread()没有正确地模仿.then()行为。
下面是我的实现,应该更接近于.then(a, b):
Promise.prototype.spread = function(a, b) {
function doSpread(fn) {
return function(args) {
if (typeof fn === "function") {
if (Array.isArray(args)) {
return fn.apply(null, args);
} else {
return fn(args);
}
} else {
return args;
}
}
}
if (typeof b !== "undefined") {
// there is a reject handler
return this.then(doSpread(a), doSpread(b));
} else {
// no reject handler
return this.then(doSpread(a));
}
}
// Array.isArray polyfill
if (!Array.isArray) {
Array.isArray = function(arg) {
return Object.prototype.toString.call(arg) === '[object Array]';
};
}工作演示和测试:https://jsfiddle.net/jfriend00/nqc0h10y/
而且,这里有一个版本,它将更改为等待在我们讨论的注释中的值数组中返回的任何承诺。我还更改了它,以便如果不将一个函数传递给.spread(),它将拒绝:
Promise.prototype.spread = function(a, b) {
function doSpread(fn) {
return function(args) {
if (typeof fn === "function") {
if (Array.isArray(args)) {
// in cases where there could be promises in the array, wait on those
return Promise.all(args).then(function(returnArgs) {
// split the array of results into separately passed arguments
return fn.apply(null, returnArgs);
});
} else {
return fn(args);
}
} else {
throw new Error("Must pass a function to .spread()");
}
}
}
if (typeof b !== "undefined") {
// there is a reject handler
return this.then(doSpread(a), doSpread(b));
} else {
// no reject handler
return this.then(doSpread(a));
}
}
// Array.isArray polyfill
if (!Array.isArray) {
Array.isArray = function(arg) {
return Object.prototype.toString.call(arg) === '[object Array]';
};
}https://codereview.stackexchange.com/questions/123574
复制相似问题