首页 > 解决方案 > javascript中承诺数组的链式执行

问题描述

我正在尝试创建一个承诺链,其中每个承诺在执行之前等待前一个承诺。

const syncStatusChanges = () => {
    return new Promise((resolve, reject) => {
        console.log("in")

        setTimeout(() => {
            console.log("done")
            resolve({ done: true })
        }, 2000);
    });
}


const run = () => {
  const promises = [syncStatusChanges(), syncStatusChanges()]
  promises[0].then(res => {
      console.log("done 1")
      promises[1].then(res => {
          console.log("done 2")
      })
  })
}

run()

在此示例中,输出为:

in
in
done
done 1
done
done 2

但我希望它是:

in
done
done 1
in
done
done 2

我还希望它适用于任意 n 个函数。我看到了这个答案,但输出是一样的!

var promise = statusChangeCalls[0];
for (var i = 1; i < statusChangeCalls.length; i++)
    promise = promise.then(statusChangeCalls[i]);

标签: javascriptpromise

解决方案


正如评论中所写。您正在执行数组本身中的函数。看到你的输出我明白了什么。下面的运行功能可以帮助你。

  const run = () => {
  const promise = syncStatusChanges();
  promise.then(res => {
     console.log("done 1")
     syncStatusChanges().then(res => {
         console.log("done 2")
     })
  })
}

承诺急切地执行。它不会等待注册 then 函数。您可以寻找observable,它们在执行时很懒惰。基本上他们会等到您订阅它们。

对于您对循环的第二个疑问。您可以使用async await关键字来实现链接。只需在 runInLoop 函数中将 number 作为参数传递,即可多次执行 Promise。

const runInLoop = async(numberOfPromisesCall)=> {
  for (let i = 0; i < numberOfPromisesCall; i++){
       await syncStatusChanges();
       console.log(`done ${i + 1}`);
  }
} 
runInLoop(5)

推荐阅读