我babel
用来转换我的node.js@0.10.x
代码,但我坚持承诺。
我需要-type 功能,例如allSettled
,我可以在其中使用。q
bluebird
angular.$q
在 babel 的 core-jsPromise
上,没有allSettled
方法。
目前我正在使用q.allSettled
作为解决方法:
import { allSettled } from 'q';
在 babel polyfill 中有类似的东西吗?或者,哪个是我尝试实现的好算法?
我babel
用来转换我的node.js@0.10.x
代码,但我坚持承诺。
我需要-type 功能,例如allSettled
,我可以在其中使用。q
bluebird
angular.$q
在 babel 的 core-jsPromise
上,没有allSettled
方法。
目前我正在使用q.allSettled
作为解决方法:
import { allSettled } from 'q';
在 babel polyfill 中有类似的东西吗?或者,哪个是我尝试实现的好算法?
有人提议将此功能添加到 ECMAScript 标准中,并且已被接受!查看Promise.allSettled
文档了解详细信息。
如果你看一下q.allSettled 的实现,你会发现它实际上很容易实现。以下是使用 ES6 Promises 实现它的方法:
function allSettled(promises) {
let wrappedPromises = promises.map(p => Promise.resolve(p)
.then(
val => ({ status: 'fulfilled', value: val }),
err => ({ status: 'rejected', reason: err })));
return Promise.all(wrappedPromises);
}
2020年答案:
其他答案试图做的是实现Promise.allSettled
自己。这已经由core-js项目完成。
你需要做的是Promise.allSettled
通过core-js为你制作 babel polyfill 。你配置它的方式是@babel/preset-env
这样的:
presets: [
['@babel/preset-env', {
useBuiltIns: 'usage',
corejs: {version: 3, proposals: true},
}],
],
在您的构建工件中,这将添加一个调用,require("core-js/modules/esnext.promise.all-settled")
将monkeypatches.allSettled
函数添加到promise API。
const allSettled = promises =>
Promise.all(promises.map(promise => promise
.then(value => ({ state: 'fulfilled', value }))
.catch(reason => ({ state: 'rejected', reason }))
));
或者,如果您坚持要填充它:
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 };
});
}));
};
}
取自这里
或者,哪个是我尝试实现的好算法?
这是我对类似事情的尝试,我有 Newsletter 服务,在我的情况下,我希望我的 allSettled 承诺在所有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;
}
这是相同功能的另一种做法:spex.batch
源代码太多了,不能在这里重新发布,所以这里只是一个如何使用它的批处理示例:
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' ]
这只是为了简化对已发生错误列表的快速访问。
我的实现将在下面
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);
});
});
});
};