Javascript 解析承诺。包含承诺数组且超时的所有承诺

Javascript 解析承诺。包含承诺数组且超时的所有承诺,javascript,promise,Javascript,Promise,在下面的示例中,我想在几秒钟后解析数组的每个元素。它现在的行为是,它将在4秒后解决承诺,我希望它在16秒后解决,因为有4个元素 const numbers = [1, 2, 3, 4]; const promises = numbers.map(number => { return new Promise(resolve => { setTimeout(() => { console.log(number);

在下面的示例中,我想在几秒钟后解析数组的每个元素。它现在的行为是,它将在4秒后解决承诺,我希望它在16秒后解决,因为有4个元素

const numbers = [1, 2, 3, 4];

const promises = numbers.map(number => {
    return new Promise(resolve => {
        setTimeout(() => {
          console.log(number);
            resolve(number);
        }, 4000);
    });
});


Promise.all(promises).then( () => {
    console.log("Done");
});

它将所有值传递给map函数,然后对它们进行迭代,并在4秒钟内为它们创建异步工作。它不会依次调用
setTimeout

您的4秒仅与
setTimeout
的回调有关,而与
map
函数无关,这意味着回调将至少在4秒后调用。因此,引擎为
setTimeout
创建不同的线程,并让它在4秒后调用。当另一个线程中的第一个线程的时间流逝时,在JS线程中,它传递第二个值,并对每个项目执行相同的操作

一个解决方案可以使用RxJS完成

Rx.Observable.from([1,2,3,4]).map(value=>Rx.Observable.of(value).delay(4000)).concatAll().subscribe(x=>console.log(x))

这是正常的行为,因为承诺是异步的,实际上是并发的。所有的承诺都只是等待所有的承诺完成,它不是一个精化队列,一个接一个地调用一个承诺。如果您想一个接一个地执行操作,只是不使用承诺,请使用正常的同步周期:)

每次递增计时器,将其乘以
数字:

const number=[1,2,3,4];
const promises=numbers.map(number=>{
返回新承诺(解决=>{
设置超时(()=>{
控制台日志(编号);
决议(编号);
},数目*4000);
});
});
承诺。所有(承诺)。然后(()=>{
控制台日志(“完成”);

});当您创建承诺时,超时将设置为4秒,并将在~4秒后同时过期。 要实现所需的行为,您可以执行以下操作:

const numbers = [1, 2, 3, 4];

const promises = numbers.map((number, i) => {
    return new Promise(resolve => {
        setTimeout(() => {
          console.log(number); 
            resolve(number);
        }, 4000*(i+1));
    });
});


Promise.all(promises).then( () => {
    console.log("Done");
});

使用新的Async/Await,现在已经广泛实现了这一点。如果没有,您可以为旧浏览器进行传输

您可以创建代码,这样更线性,更容易理解

还值得一提的是,bluebird有一个基于承诺的映射,它有一个并发选项,非常适合映射位

const number=[1,2,3,4];
异步函数延迟(毫秒){
返回新承诺((解决)=>{
设置超时(解析,毫秒);
});
}
//假装显示数字异步
异步函数showNumber(l){
返回新承诺((解决)=>{
setTimeout(()=>{console.log(数字[l]);resolve();});
});
}
异步函数doNumbers(){
for(设l=0;ldoNumbers()如果您需要按顺序而不是并行运行每个承诺。
您可以使用异步函数,然后依次使用等待。
对于非异步函数解决方案,可以使用此功能性较旧的解决方案。使用数组归约方法。注意,我正在生成一个函数数组,每个函数都返回一个承诺

const numbers = [1, 2, 3, 4];

numbers.map(number => () => {
    return new Promise(resolve => {
       setTimeout(() => {
           console.log(number);
           resolve(number);
       }, 4000);
    });
}).reduce(
    (promise, asyncJob) => promise.then(() => asyncJob()),
    Promise.resolve()
).then(() => { console.log('done'); });

谢谢您的回复,但我正在寻找解决方案,我该怎么做?请参阅编辑后的答案。使用simple
setTimeout
有点困难,如果您不想增加延迟时间,谢谢您的回答,我认为这是最优雅的方式。回答不错,但行为与预期略有不同。第一次showNumber调用立即发生(应该延迟),并且“完成”打印在最后一次showNumber调用后4秒发生。您应该交换这两行:等待延迟(4000);等待显示编号(l)@RogerC,是的。。说得好。我将交换它们以与OP保持一致。