javascript - 如何在 JavaScript 中将 Promise 链接在一起
问题描述
我正在尝试链接一系列Promise
s ,以便第二个承诺将在第一个承诺解决后开始,依此类推。我不明白我怎么不能让它正常工作。
这是我的演示代码:
const promise1 = new Promise((resolve, reject) => { setTimeout(resolve, 5000, 'a'); });
const promise2 = new Promise((resolve, reject) => { setTimeout(resolve, 5000, 'b'); });
const promise3 = new Promise((resolve, reject) => { setTimeout(resolve, 5000, 'c'); });
promise1.then(val => {
console.log('promise 1', val);
promise2.then(val2 => {
console.log('promise 2', val2);
promise3.then(val3 => {
console.log('promise 3', val3);
});
});
});
所以我对这段代码的期望是这样的:
--- 5 seconds passes ---
// console outputs: 'promise 1a'
--- 5 seconds passes ---
// console outputs: 'promise 2b'
--- 5 seconds passes ---
// console outputs: 'promise 3c'
但相反会发生什么:
--- 5 seconds passes ---
// console outputs: 'promise 1a'
// console outputs: 'promise 2b'
// console outputs: 'promise 3c'
为什么会这样?为什么三个 Promise 同时触发?
解决方案
为了解释为什么它们都同时完成,我们可以忽略除 Promise 声明之外的所有内容:
const promise1 = new Promise((resolve, reject) => { setTimeout(resolve, 5000, 'a'); });
const promise2 = new Promise((resolve, reject) => { setTimeout(resolve, 5000, 'b'); });
const promise3 = new Promise((resolve, reject) => { setTimeout(resolve, 5000, 'c'); });
这些 Promise 是HOT创建的(即立即调用传递给构造函数的处理程序),并且都是同时创建的。因此setTimeout
,无论随后如何使用,inside 将在 5 秒内触发。
随后如何使用它们是附带的,但是,为了让您的示例正常工作,编写调用时返回Promise 的函数可能会更好......所以:
const getPromise1 = () => new Promise((resolve, reject) => {
setTimeout(resolve, 5000, 'a');
});
const getPromise2 = () => new Promise((resolve, reject) => {
setTimeout(resolve, 5000, 'b');
});
const getPromise3 = () => new Promise((resolve, reject) => {
setTimeout(resolve, 5000, 'c');
});
getPromise1().then((val1) => {
console.log(val1);
return getPromise2(); //by returning Promise, you can avoid deep nesting
}).then((val2) => {
console.log(val2);
return getPromise3();
}).then((val3) => {
console.log(val3);
});
在回答评论时,最好有一个参数数组用于提供给 Promise-returning 函数,然后用于async/await
编写一个按顺序调用 Promise-returning 函数的函数
const getPromise = (v) => new Promise((resolve, reject) => {
setTimeout(resolve, 5000, v);
});
async function run(params) {
for (const p of params) {
const returnVal = await getPromise(p);
console.log(returnVal);
}
}
run(['a', 'b', 'c']);
推荐阅读
- instagram - How to fetch my followers Instagram Activity via API?
- python-3.x - 无法通过 Python 中的 API 请求获取数据
- python - 如何用 aruco 解释 rvecs
- javascript - 使用 JQuery 在 HTML 按钮中运行 python 脚本
- c++11 - 为什么g ++处理'using'定义的命名空间与typedefs不同
- jquery - 使用 ajax.reload() 刷新 jQuery DataTable 并将数据发送到服务器
- ssl - Apache httpd“过时的连接设置”
- python - extract several fasta file with a list of ID (in order)
- google-maps - Google Maps Directions API 出现错误
- python - 使用样式时如何防止 Matplotlib 覆盖 rcParams?