如何在等待承诺解决的同时执行代码?

发布于 2025-02-06 14:09:11 字数 793 浏览 0 评论 0原文

查看此示例代码:

var arrayToSend = [1,2,3,4,5,6,7,8,9]

function send(x){ // 'sends' the value. resolves after 1 second.
    return new Promise(resolve=>{
        setTimeout(()=>{
            resolve()
            console.log('sent '+x)
            },1000)
    })
}

function calculate(x){return x**2} // just an example, there would be something expensive here.

async function loopAndSendArray(){ 
    for (let val of arrayToSend){
        let calculatedVal = calculate(val)     //calculate this when waiting for the send promise to finish BUT don't send the value until it's resolved
        await send(calculatedVal)}
}

我希望脚本呼叫calculate()在等待send()前一个值的下一个值时要完成(以节省时间,否则将花费在承诺后计算它)。它不会以下一个值调用下一个send(),直到解决第一个值。

Take a look at this example code:

var arrayToSend = [1,2,3,4,5,6,7,8,9]

function send(x){ // 'sends' the value. resolves after 1 second.
    return new Promise(resolve=>{
        setTimeout(()=>{
            resolve()
            console.log('sent '+x)
            },1000)
    })
}

function calculate(x){return x**2} // just an example, there would be something expensive here.

async function loopAndSendArray(){ 
    for (let val of arrayToSend){
        let calculatedVal = calculate(val)     //calculate this when waiting for the send promise to finish BUT don't send the value until it's resolved
        await send(calculatedVal)}
}

I'd like the script to call calculate() for the next value when it's waiting for the send() promise of the former value to finish (to save time that would otherwise be spent calculating it after the promise). It would not call the next send() with the next value until the first one is resolved.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

大海や 2025-02-13 14:09:11

与其等待发送的调用,不如将调用分配给外部变量,然后在下一个迭代中调用计算后等待等待。

var arrayToSend = [1, 2, 3, 4, 5, 6, 7, 8, 9]

function send(x) {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve()
      console.log('sent ' + x)
    }, 1000)
  })
}

function calculate(x) {
  return x ** 2
}

async function loopAndSendArray() {
  let lastSend;
  for (const val of arrayToSend) {
    const calculatedVal = calculate(val);
    await lastSend;
    lastSend = send(calculatedVal)
  }
  await lastSend;
}
loopAndSendArray();

无论计算是否需要比网络请求更多的时间,如果必须在串行中提出请求(如当前代码所做的那样),这都是最佳的。如果可以并行提出请求,并且计算时间少于网络请求,则可以一次计算并发送多个(或全部)。

Instead of awaiting the call to send, assign the call to an outside variable, and then await it after calling calculate in the next iteration.

var arrayToSend = [1, 2, 3, 4, 5, 6, 7, 8, 9]

function send(x) {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve()
      console.log('sent ' + x)
    }, 1000)
  })
}

function calculate(x) {
  return x ** 2
}

async function loopAndSendArray() {
  let lastSend;
  for (const val of arrayToSend) {
    const calculatedVal = calculate(val);
    await lastSend;
    lastSend = send(calculatedVal)
  }
  await lastSend;
}
loopAndSendArray();

This is optimal no matter whether the calculation takes more or less time than the network request, if the requests have to be made in serial (as your current code is doing). If the requests can be made in parallel and the calculation takes less time than the network request, you could calculate and send multiple (or all) at once.

念﹏祤嫣 2025-02-13 14:09:11

由于async/等待是固有的顺序,因此您想以不同的顺序进行操作,但是此代码应该这样做:

async function loopAndSendArray() {
    let prevPromise;
    for (let val of arrayToSend) {
        let calculatedVal = calculate(val)
        await prevPromise;
        prevPromise = send(calculatedVal);
        // prevent unhandled rejections crashing the app in case `calculate` throws
        prevPromise.catch(e => {/* ignore */});
    }
    await prevPromise;
}

There is no nice way to implement this, since async/await is inherently sequential and you want to do things in a different order, but this code should do it:

async function loopAndSendArray() {
    let prevPromise;
    for (let val of arrayToSend) {
        let calculatedVal = calculate(val)
        await prevPromise;
        prevPromise = send(calculatedVal);
        // prevent unhandled rejections crashing the app in case `calculate` throws
        prevPromise.catch(e => {/* ignore */});
    }
    await prevPromise;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文