Promise.all 替换?

Sye*_*Ali 7 javascript parallel-processing asynchronous

有没有什么方法可以在 Javascript 中调用多个异步函数,但在一个函数完成后立即获得调用响应,这与等待所有异步调用完成的 Promise.all 不同?我想要的是,并行运行异步调用,并在其他调用仍在运行时立即获取相应调用的响应,然后更新反应状态。

我已经在使用 Promise.all 进行多个异步调用,但它会在所有调用完成时给出响应。

kap*_*zak 5

您可以迭代一系列 Promise 并更改每个 Promise 解析的状态:

let state = null;

const p1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve({p1: 1});
  }, 2000);
});
const p2 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve({p2: 2});
  }, 1000);
});
const p3 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve({p3: 3});
  }, 3000);
});

// Iterate promises
[p1, p2, p3].forEach(p => {
  p.then(res => {
    state = Object.assign({}, state, res);
    console.log(state);
  });
});

console.log(state);
Run Code Online (Sandbox Code Playgroud)

Promise您可以为此任务创建自己的方法:

if (!Promise.each) {
  Promise.each = function(promises, callback, error) {
    if (promises && Array.isArray(promises)) {
      promises.forEach(p => {
        p.then(res => {
          callback(res);
        }, err => {
          if (error) {
              error(err);
          } else {
              console.log(err);
          }          
        });
      });
    }
  }
}

// Usage
Promise.each([p1, p2, p3], updateState);
Run Code Online (Sandbox Code Playgroud)


Mx.*_*olf 3

在你的问题中,短语“比更新......状态”是关键。您计划以这样一种方式更新状态:一旦一个承诺“完成”,相应的状态就会更新。你一直在尝试这样的事情

async function f1(){ await Promise.resolve(); }
async funciton f2(){ await Promise.resolve(); }
async function fn(){ await Promise.resolve(); }

async function drvAsync(){
  const [r1, r2, rn] = await Promise.all([f1(), f2(), fn()]);
  u1(r1);
  u2(r2);
  un(rn);
}
Run Code Online (Sandbox Code Playgroud)

其中 f[n] 是异步业务函数,u[n] 是处理其结果的方法。此架构在您的场景中是不可接受的。也许 fn 比其他的完成得更快,并且您想更早地更新第 N 个状态。

我的建议是根本不使用同步原语。相反,您应该单独处理结果。

function drv(){
  f1().then((r1)=>u1(r1)).catch((e)=>er(e));
  f2().then((r2)=>u2(r2)).catch((e)=>er(e));
  fn().then((rn)=>un(rn)).catch((e)=>er(e));;  
}
Run Code Online (Sandbox Code Playgroud)

此模式将调用每个 update (u[n]) 方法,而无需等待其他方法的结果。