首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Promise.spread“聚脂”

Promise.spread“聚脂”
EN

Code Review用户
提问于 2016-03-22 19:17:20
回答 1查看 325关注 0票数 2

我已经为Chrome的Promise对象编写了这个“多填充”,并且我对实现有一些关注;

  1. 它真的像设计的那样工作吗?这似乎是可行的,但我不确定是否有“边缘情况”,我没有考虑。
  2. 有更好的方法吗?内部函数的方式似乎有点奇怪,因为我不喜欢我的promise[method]工作方式。

以下是扩展方法的工作原理:

代码语言:javascript
复制
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
});

以下是我的实现:

代码语言:javascript
复制
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;
};
EN

回答 1

Code Review用户

回答已采纳

发布于 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)

代码语言:javascript
复制
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(),它将拒绝:

代码语言:javascript
复制
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://jsfiddle.net/jfriend00/om5auzs0/

票数 3
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/123574

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档