蓝鸟的承诺链数组
chain array of promises with bluebird
我正在按照我的方式工作,但我被我的用例困住了。
我有一个转换器函数数组(每个函数都是一个承诺并修改一些 JSON 结构)。
让我展示一些代码。
假设这是我的 JSON 结构(数组)
var data = [{a: 1, b:2}, {a:3, b:4}];
transformFunction
是以某种方式修改数据的转换函数的定义。这两个函数在上面的JSON结构中添加了c
和d
属性:
var transformFunctions = { //
transform1: function (data) { // This function adds `c` property to each object from `a`
return new Promise(function (resolve) {
for (var i = 0; i < data.length; i++) {
data[i].c = data[i].a;
}
return resolve(data);
})
},
transform2: function (data) { // This function adds `d` property to each object from `c`
return new Promise(function (resolve) {
for (var i = 0; i < data.length; i++) {
data[i].d = data[i].c;
}
return resolve(data);
})
},
...
}
来自 UI 的用户指定他应该使用哪些转换器功能以及使用顺序。假设他选择了这样的正常顺序:
var userTransformList = ['transform1', 'transform2'];
transform1
方法应该修改数据,结果应该传递给transform2
方法。
我在看:Promise.all
但它似乎不关心承诺的顺序,最重要的是它需要将上一个结果传递给下一个承诺。
注意: 正如 adeneo 在评论中指出的那样,只有在处理异步代码时才使用 promises。
创建一个要执行的函数数组。并确保它们都是 return 一个 Promise。
然后,您可以使用 Promise.reduce
通过 returning 执行当前承诺的结果 returning 函数将初始值减少为转换后的最终值, 在每次迭代中。
最后,您可以附加一个 then
处理程序来获取实际值和一个 catch
处理程序,以防承诺被拒绝。
假设我们有两个这样的转换函数。
注:我再说一遍。你永远不应该将 Promises 与这些功能一起使用。仅当您处理的函数真正异步时才应使用 promises。
// Just add a property called `c` to all the objects and return a Promise object
function transform1(data) {
return Promise.resolve(data.map(function(currentObject) {
currentObject.c = currentObject.a + currentObject.b;
return currentObject;
}));
}
// Just add a property called `d` to all the objects and return a Promise object
function transform2(data) {
return Promise.resolve(data.map(function(currentObject) {
currentObject.d = currentObject.a + currentObject.b + currentObject.c;
return currentObject;
}));
}
然后就可以对原值进行变换,像这样
Promise.reduce([transform1, transform2], function (result, currentFunction) {
return currentFunction(result);
}, [{a: 1, b: 2}, {a: 3, b: 4}]) // Initial value
.then(function (transformedData) {
console.log(transformedData);
})
.catch(function (err) {
console.error(err);
});
输出
[ { a: 1, b: 2, c: 3, d: 6 }, { a: 3, b: 4, c: 7, d: 14 } ]
您可以像往常一样链接 Promises:使用 .then()
.
假设您有这两个转换:
function increment(x) {
return Promise.resolve(x + 1);
}
function double(x) {
return Promise.resolve(2 * x);
}
在真实场景中,这些将执行异步工作。你可以:
increment(1).then(double)
但是,你不知道变换的顺序和次数。让我们将它们放入一个数组中,然后 then()
一个一个:
var transformations = [increment, double]
var promise = Promise.resolve(1);
for (var i = 0; i < transformations.length; i++)
promise = promise.then(transformations[i]);
您可以在开始前、完成后甚至每次转换时附加 catch()
处理程序。
如果您要应用数百个转换,则效率不高。在这种情况下,您应该使用 reduce()
作为 thefourtheye 在他的回答中建议的那样。
我正在按照我的方式工作,但我被我的用例困住了。 我有一个转换器函数数组(每个函数都是一个承诺并修改一些 JSON 结构)。
让我展示一些代码。
假设这是我的 JSON 结构(数组)
var data = [{a: 1, b:2}, {a:3, b:4}];
transformFunction
是以某种方式修改数据的转换函数的定义。这两个函数在上面的JSON结构中添加了c
和d
属性:
var transformFunctions = { //
transform1: function (data) { // This function adds `c` property to each object from `a`
return new Promise(function (resolve) {
for (var i = 0; i < data.length; i++) {
data[i].c = data[i].a;
}
return resolve(data);
})
},
transform2: function (data) { // This function adds `d` property to each object from `c`
return new Promise(function (resolve) {
for (var i = 0; i < data.length; i++) {
data[i].d = data[i].c;
}
return resolve(data);
})
},
...
}
来自 UI 的用户指定他应该使用哪些转换器功能以及使用顺序。假设他选择了这样的正常顺序:
var userTransformList = ['transform1', 'transform2'];
transform1
方法应该修改数据,结果应该传递给transform2
方法。
我在看:Promise.all
但它似乎不关心承诺的顺序,最重要的是它需要将上一个结果传递给下一个承诺。
注意: 正如 adeneo 在评论中指出的那样,只有在处理异步代码时才使用 promises。
创建一个要执行的函数数组。并确保它们都是 return 一个 Promise。
然后,您可以使用
Promise.reduce
通过 returning 执行当前承诺的结果 returning 函数将初始值减少为转换后的最终值, 在每次迭代中。最后,您可以附加一个
then
处理程序来获取实际值和一个catch
处理程序,以防承诺被拒绝。
假设我们有两个这样的转换函数。
注:我再说一遍。你永远不应该将 Promises 与这些功能一起使用。仅当您处理的函数真正异步时才应使用 promises。
// Just add a property called `c` to all the objects and return a Promise object
function transform1(data) {
return Promise.resolve(data.map(function(currentObject) {
currentObject.c = currentObject.a + currentObject.b;
return currentObject;
}));
}
// Just add a property called `d` to all the objects and return a Promise object
function transform2(data) {
return Promise.resolve(data.map(function(currentObject) {
currentObject.d = currentObject.a + currentObject.b + currentObject.c;
return currentObject;
}));
}
然后就可以对原值进行变换,像这样
Promise.reduce([transform1, transform2], function (result, currentFunction) {
return currentFunction(result);
}, [{a: 1, b: 2}, {a: 3, b: 4}]) // Initial value
.then(function (transformedData) {
console.log(transformedData);
})
.catch(function (err) {
console.error(err);
});
输出
[ { a: 1, b: 2, c: 3, d: 6 }, { a: 3, b: 4, c: 7, d: 14 } ]
您可以像往常一样链接 Promises:使用 .then()
.
假设您有这两个转换:
function increment(x) {
return Promise.resolve(x + 1);
}
function double(x) {
return Promise.resolve(2 * x);
}
在真实场景中,这些将执行异步工作。你可以:
increment(1).then(double)
但是,你不知道变换的顺序和次数。让我们将它们放入一个数组中,然后 then()
一个一个:
var transformations = [increment, double]
var promise = Promise.resolve(1);
for (var i = 0; i < transformations.length; i++)
promise = promise.then(transformations[i]);
您可以在开始前、完成后甚至每次转换时附加 catch()
处理程序。
如果您要应用数百个转换,则效率不高。在这种情况下,您应该使用 reduce()
作为 thefourtheye 在他的回答中建议的那样。