Javascript 连锁承诺
Javascript chained promises
我在演示代码中使用 setTimeout 函数模拟了 3 个 ajax 调用。我将从一段运行良好的代码开始:所有调用都是并行进行的,我希望所有调用都成功,否则会出现错误。
var p1 = function () {
return new Promise(function (resolve, reject) {
setTimeout(function () {
console.log('p1');
resolve(1);
//reject(1);
}, 2000);
});
};
var p2 = function () {
return new Promise(function (resolve, reject) {
setTimeout(function () {
console.log('p2');
resolve(2);
//reject(2);
}, 1000);
});
};
var p3 = function () {
return new Promise(function (resolve, reject) {
setTimeout(function () {
console.log('p3');
resolve(3);
//reject(3);
}, 5000);
});
};
Promise.all([p1(), p2(), p3()])
.then(values => {
console.log(values);
}).catch(values => {
console.log("error: " + values);
});
现在,要进行的重要更改是 p2 必须仅在 p1 成功结束后执行,而在其他情况下则不执行。这是新代码,但这个根本行不通:
var p1 = function () {
return new Promise(function (resolve, reject) {
setTimeout(function () {
console.log('p1');
resolve(1);
//reject(1);
}, 2000);
});
};
var p2 = function () {
return new Promise(function (resolve, reject) {
setTimeout(function () {
console.log('p2');
resolve(2);
//reject(2);
}, 1000);
});
};
var p21 = function() {
return new Promise(function (resolve, reject) {
p1().then(function (data) { p2(); })
});
};
var p3 = function () {
return new Promise(function (resolve, reject) {
setTimeout(function () {
console.log('p3');
resolve(3);
//reject(3);
}, 5000);
});
};
Promise.all([p21(), p3()])
.then(values => {
console.log(values);
}).catch(values => {
console.log("error: " + values);
});
我已经阅读了各种关于如何处理 JS promises 的教程,但我仍然无法解决我的问题。
请注意,测试函数中使用的时间延迟只是一个示例,代码应该可以正常工作,而不管函数的相对持续时间如何(即天气每个函数更慢或更快)。
您可以通过在前一个 promise 的 next() 函数中返回下一个 promise 调用来使 promise 同步。听起来很复杂其实很简单:
/*
* Remains the very same
*/
var p1 = function () {
return new Promise(function (resolve, reject) {
setTimeout(function () {
console.log('p1');
resolve(1);
//reject(1);
}, 2000);
});
};
var p2 = function () {
return new Promise(function (resolve, reject) {
setTimeout(function () {
console.log('p2');
resolve(2);
//reject(2);
}, 1000);
});
};
var p3 = function () {
return new Promise(function (resolve, reject) {
setTimeout(function () {
console.log('p3');
resolve(3);
//reject(3);
}, 5000);
});
};
// If you want to run p1 and p3 in "parallel" + after p1 is finished run p2
Promise.all([p1().then(valuesFromP1 => {
return p2();
}), p3()]).then(values => {
// all 3 finished
})
// Or alternatively something similar but slightly different - see the comments
Promise.all([p1().then(valuesFromP1 => {
// handle p1 is done
p2().then(valuesFromP2 => {
// handle p2 is done
});
}), p3()])
.then(values => {
// handle p1 and p3 are done but you don't care about p2
});
// Or if you don't care about common finish you can simply do this
p1().then(valuesFromP1 => {
// handle p1 is done
p2().then(valuesFromP2 => {
// handle p2 is done
});
});
p3().then(valuesFromP3 => {
// handle p3 is done
});
弗兰克
我相信您的第二个代码集中缺少的是返回结果。您的内心承诺不仅没有 "return p2",而且您没有使用正在生成的 resolve/reject 函数。对于初学者,我会避免创建新的 Promise 对象作为解析其他对象的方式——通常,这可以通过更好地理解 promise 库(使用 then
或 all
)来完成。
// this function returns a 2-long array (inside a promise), so you may want to change
// the calling syntax
var p21 = function() {
// Do not "return promise" - we create a new one just by calling "then()"
//return new Promise(function (resolve, reject) {
return p1().then(function (data) {
return p2().then(function(data2) {
return [data, data2];
});
});
};
我在演示代码中使用 setTimeout 函数模拟了 3 个 ajax 调用。我将从一段运行良好的代码开始:所有调用都是并行进行的,我希望所有调用都成功,否则会出现错误。
var p1 = function () {
return new Promise(function (resolve, reject) {
setTimeout(function () {
console.log('p1');
resolve(1);
//reject(1);
}, 2000);
});
};
var p2 = function () {
return new Promise(function (resolve, reject) {
setTimeout(function () {
console.log('p2');
resolve(2);
//reject(2);
}, 1000);
});
};
var p3 = function () {
return new Promise(function (resolve, reject) {
setTimeout(function () {
console.log('p3');
resolve(3);
//reject(3);
}, 5000);
});
};
Promise.all([p1(), p2(), p3()])
.then(values => {
console.log(values);
}).catch(values => {
console.log("error: " + values);
});
现在,要进行的重要更改是 p2 必须仅在 p1 成功结束后执行,而在其他情况下则不执行。这是新代码,但这个根本行不通:
var p1 = function () {
return new Promise(function (resolve, reject) {
setTimeout(function () {
console.log('p1');
resolve(1);
//reject(1);
}, 2000);
});
};
var p2 = function () {
return new Promise(function (resolve, reject) {
setTimeout(function () {
console.log('p2');
resolve(2);
//reject(2);
}, 1000);
});
};
var p21 = function() {
return new Promise(function (resolve, reject) {
p1().then(function (data) { p2(); })
});
};
var p3 = function () {
return new Promise(function (resolve, reject) {
setTimeout(function () {
console.log('p3');
resolve(3);
//reject(3);
}, 5000);
});
};
Promise.all([p21(), p3()])
.then(values => {
console.log(values);
}).catch(values => {
console.log("error: " + values);
});
我已经阅读了各种关于如何处理 JS promises 的教程,但我仍然无法解决我的问题。
请注意,测试函数中使用的时间延迟只是一个示例,代码应该可以正常工作,而不管函数的相对持续时间如何(即天气每个函数更慢或更快)。
您可以通过在前一个 promise 的 next() 函数中返回下一个 promise 调用来使 promise 同步。听起来很复杂其实很简单:
/*
* Remains the very same
*/
var p1 = function () {
return new Promise(function (resolve, reject) {
setTimeout(function () {
console.log('p1');
resolve(1);
//reject(1);
}, 2000);
});
};
var p2 = function () {
return new Promise(function (resolve, reject) {
setTimeout(function () {
console.log('p2');
resolve(2);
//reject(2);
}, 1000);
});
};
var p3 = function () {
return new Promise(function (resolve, reject) {
setTimeout(function () {
console.log('p3');
resolve(3);
//reject(3);
}, 5000);
});
};
// If you want to run p1 and p3 in "parallel" + after p1 is finished run p2
Promise.all([p1().then(valuesFromP1 => {
return p2();
}), p3()]).then(values => {
// all 3 finished
})
// Or alternatively something similar but slightly different - see the comments
Promise.all([p1().then(valuesFromP1 => {
// handle p1 is done
p2().then(valuesFromP2 => {
// handle p2 is done
});
}), p3()])
.then(values => {
// handle p1 and p3 are done but you don't care about p2
});
// Or if you don't care about common finish you can simply do this
p1().then(valuesFromP1 => {
// handle p1 is done
p2().then(valuesFromP2 => {
// handle p2 is done
});
});
p3().then(valuesFromP3 => {
// handle p3 is done
});
弗兰克
我相信您的第二个代码集中缺少的是返回结果。您的内心承诺不仅没有 "return p2",而且您没有使用正在生成的 resolve/reject 函数。对于初学者,我会避免创建新的 Promise 对象作为解析其他对象的方式——通常,这可以通过更好地理解 promise 库(使用 then
或 all
)来完成。
// this function returns a 2-long array (inside a promise), so you may want to change
// the calling syntax
var p21 = function() {
// Do not "return promise" - we create a new one just by calling "then()"
//return new Promise(function (resolve, reject) {
return p1().then(function (data) {
return p2().then(function(data2) {
return [data, data2];
});
});
};