Promise.all在babel ES6实现中安装

时间:2015-06-01 08:46:18

标签: javascript node.js ecmascript-6 babeljs es6-promise

我使用babel来转换我的node.js@0.10.x代码,并且我坚持承诺。

我需要allSettled - 我可以在qbluebirdangular.$q中使用的类型功能。

关于babel的核心j Promise,没有allSettled方法。

目前,我使用q.allSettled作为解决方法:

import { allSettled } from 'q';

babel polyfill中有类似的东西吗?或者,这对我来说是一个很好的算法?

7 个答案:

答案 0 :(得分:16)

如果您查看implementation of q.allSettled,您会发现它实际上非常简单。以下是使用ES6 Promises实现它的方法:

function allSettled(promises) {
    let wrappedPromises = promises.map(p => Promise.resolve(p)
        .then(
            val => ({ state: 'fulfilled', value: val }),
            err => ({ state: 'rejected', reason: err })));
    return Promise.all(wrappedPromises);
}

答案 1 :(得分:8)

2020年答案:

其他答案正在尝试做的是自己实现Promise.allSettledcore-js项目已经完成了这项工作。

您需要做的是通过core-js为您制作babel polyfill Promise.allSettled。配置它的方式是通过@babel/preset-env进行,如下所示:

presets: [
    ['@babel/preset-env', {
        useBuiltIns: 'usage',
        corejs: {version: 3, proposals: true},
    }],
],

在您的构建工件中,这将添加对require("core-js/modules/esnext.promise.all-settled")的调用,从而将.allSettled函数修补到promises API。

答案 2 :(得分:2)

  

或者,这对我来说是一个很好的算法?

  1. 使用executor function
  2. 创建新承诺
  3. 在执行者范围内使用计数器/结果数组
  4. 使用每个父承诺注册then()回调,将结果保存在数组
  5. 当计数器指示所有父承诺已完成
  6. 时,从步骤1解决/拒绝承诺

答案 3 :(得分:2)

const allSettled = promises =>
  Promise.all(promises.map(promise => promise
    .then(value => ({ state: 'fulfilled', value }))
    .catch(reason => ({ state: 'rejected', reason }))
  ));

或者如果你坚持对它进行 polyfill:

if (Promise && !Promise.allSettled) {
  Promise.allSettled = function (promises) {
    return Promise.all(promises.map(function (promise) {
      return promise.then(function (value) {
        return { state: 'fulfilled', value: value };
      }).catch(function (reason) {
        return { state: 'rejected', reason: reason };
      });
    }));
  };
}

取自here

答案 4 :(得分:1)

这是我尝试类似的东西,我有通讯服务,在我的情况下,我希望我的allSettled承诺解决所有结果(拒绝和解决方案)的数组, IN ORDER , email_promises已经解决(所有电子邮件都已发布):

Newsletter.prototype.allSettled = function(email_promises) {
    var allSettledPromise = new Promise(function(resolve, reject) {
        // Keep Count
        var counter = email_promises.length;

        // Keep Individual Results in Order
        var settlements = [];
        settlements[counter - 1] = undefined;

        function checkResolve() {
            counter--;
            if (counter == 0) {
                resolve(settlements);
            }
        }

        function recordResolution(index, data) {
            settlements[index] = {
                success: true,
                data: data
            };
            checkResolve();
        }

        function recordRejection(index, error) {
            settlements[index] = {
                success: false,
                error: error
            };
            checkResolve();
        }

        // Attach to all promises in array
        email_promises.forEach(function(email_promise, index) {
            email_promise.then(recordResolution.bind(null, index))
                .catch(recordRejection.bind(null, index));
        });
    });
    return allSettledPromise;
}

答案 5 :(得分:0)

以下是另一个相同功能:spex.batch

source code在此处重新发布会太多,所以这里只是batch processing如何使用它的示例:

var spex = require('spex')(Promise);

// function that returns a promise;
function getWord() {
    return Promise.resolve("World");
}

// function that returns a value;
function getExcl() {
    return '!';
}

// function that returns another function;
function nested() {
    return getExcl;
}

var values = [
    123,
    "Hello",
    getWord,
    Promise.resolve(nested)
];

spex.batch(values)
    .then(function (data) {
        console.log("DATA:", data);
    }, function (reason) {
        console.log("REASON:", reason);
    });

输出:

DATA: [ 123, 'Hello', 'World', '!' ]

现在让我们通过将getWord更改为:

来使其失败
function getWord() {
    return Promise.reject("World");
}

现在输出是:

REASON: [ { success: true, result: 123 },
  { success: true, result: 'Hello' },
  { success: false, result: 'World' },
  { success: true, result: '!' } ]

即。整个数组已结算,报告索引限制结果。

如果不是报告完整原因,我们会调用getErrors()

console.log("REASON:", reason.getErrors());

然后输出将是:

REASON: [ 'World' ]

这只是为了简化对发生的错误列表的快速访问。

答案 6 :(得分:-1)

我的实现将在下面

Promise.prototype.myAllSettled = function (arr = []) {
  return new Promise(function processIterable(resolve, reject) {
    let result = [];
    arr.forEach((item) => {
      item
        .then((value) => {
          result.push({ status: "fulfilled", value: value });
          if (arr.length === result.length) resolve(result);
        })
        .catch((err) => {
          result.push({ status: "rejected", reason: `${err}` });
          if (arr.length === result.length) resolve(result);
        });
    });
  });
};