我有一个promise对象数组,必须按照它们在数组中列出的相同顺序进行解析,即我们不能尝试解析一个元素,直到前一个元素被解析(如方法所示Promise.all([...])).
如果一个元素被拒绝,我需要链接立即拒绝,而不尝试解析以下元素.
我该如何实现这个,或者是否存在这种sequence模式的现有实现?
function sequence(arr) {
return new Promise(function (resolve, reject) {
// try resolving all elements in 'arr',
// but strictly one after another;
});
}
Run Code Online (Sandbox Code Playgroud)
编辑
初始答案表明我们只能sequence得到这些数组元素的结果,而不是它们的执行结果,因为它是在这样的例子中预定义的.
但是,如何以避免早期执行的方式生成一系列承诺呢?
这是一个修改过的例子:
function sequence(nextPromise) {
// while nextPromise() creates and returns another promise,
// continue resolving it;
}
Run Code Online (Sandbox Code Playgroud)
我不想把它变成一个单独的问题,因为我认为它是同一个问题的一部分.
解
下面的一些答案和随后的讨论有点误入歧途,但最终解决方案完全符合我的要求,是在spex库中实现的,作为方法序列.该方法可以迭代一系列动态长度,并根据应用程序的业务逻辑创建promise.
后来我把它变成了一个供大家使用的共享库.
试图弄清楚如何找到与async.eachSeries完全相同的功能,我需要一个按顺序运行的异步动作列表(不是并行)但是找不到在原生ES6中执行它的方法,任何人都可以建议,请?
ps考虑了发电机/产量,但还没有经验,所以我没有意识到它究竟能帮助我.
编辑1
根据请求,这是一个例子:
假设这段代码:
let model1 = new MongooseModel({prop1: "a", prop2: "b"});
let model2 = new MongooseModel({prop1: "c", prop2: "d"});
let arr = [model1 , model2];
Run Code Online (Sandbox Code Playgroud)
现在,我想在一系列中运行它,而不是并行,所以使用"异步"NPM很容易:
async.eachSeries(arr, (model, next)=>{
model.save.then(next).catch(next);
}, err=>{
if(err) return reject(error);
resolve();
})
Run Code Online (Sandbox Code Playgroud)
我的问题是:使用ES6,我可以原生使用吗?没有NPM'异步'包?
编辑2
使用async/await可以轻松完成:
let model1 = new MongooseModel({prop1: "a", prop2: "b"});
let model2 = new MongooseModel({prop1: "c", prop2: "d"});
let arr = [model1 , model2];
for(let model of arr){
await model.save();
}
Run Code Online (Sandbox Code Playgroud) 假设我使用以下代码来运行一系列的promises:
let paramerterArr = ['a','b','c','d','e','f']
parameterArr.reduce(function(promise, item) {
return promise.then(function(result) {
return mySpecialFunction(item);
})
}, Promise.resolve())
Run Code Online (Sandbox Code Playgroud)
代码只是调用mySpecialFunction(它返回一个promise),等待解析的promise,然后再次调用mySpecialFunction等等.因此,对于数组中的每个元素,按正确的顺序调用该函数一次.
我怎样才能确保每次通话之间至少有50毫秒的延迟mySpecialFunction(item)?
重要的是承诺以正确的顺序执行,执行时间mySpecialFunction每次都不同.
我想同步睡眠会起作用,但我不打算在一个单独的线程中运行这个代码,因此它会在浏览器中引起恼人的ui冻结.
我不确定是否可以以某种方式使用setTimer.我的意思是我不能拖延承诺的回归.
我有一个请求承诺,我需要执行一个循环,如:
var ids = [1,2,3];
doPromise(1).then(function(){
doPromise(2).then(function(){
doPromise(3);
}
})
Run Code Online (Sandbox Code Playgroud)
问题是我永远不知道数组中有多少元素,所以我需要一个动态模式.是否可以混合同步和异步世界,以便一时只有一个请求处于活动状态(序列不重要)?
我需要对某些外部 API 执行循环调用,但有一定的延迟,以防止“超出用户速率限制”限制。
Google 地图地理编码 API 对“请求/秒”敏感,允许 10 个请求/秒。我应该对数百个联系人进行地理编码,而这样的延迟是必需的。因此,我需要 10 个异步地理编码函数,每个函数的后延迟为 1 秒。因此,我收集数组中的所有联系人,然后以异步方式循环遍历数组。
一般来说,我需要有 N 个并发线程,每个线程结束时有 D 毫秒的延迟。整个循环迭代用户实体数组。像往常一样,每个线程处理单个实体。
我想有这样的代码:
const N = 10; # threads count
const D = 1000; # delay after each execution
var processUser = function(user, callback){
someBusinessLogicProc(user, function(err) {
setTimeout(function() {
return callback(err);
}, D);
});
}
var async = require('async') ;
var people = new Array(900);
async.batchMethod(people, processUser, N, finalCallback);
Run Code Online (Sandbox Code Playgroud)
在这个伪代码中batchMethod是我要求的方法。
javascript ×4
promise ×3
ecmascript-6 ×2
es6-promise ×2
async.js ×1
asynchronous ×1
delay ×1
loops ×1
node-async ×1
node.js ×1