JavaScript Promises:按顺序执行 Promise
JavaScript Promises: Executing Promises Sequentially
为了更清楚地理解承诺,我一直在阅读一些非常有趣的文章。我遇到了以下代码,它非常适合顺序执行承诺。但我无法理解它是如何工作的。
function doFirstThing(){
return new Promise(function(resolve,reject){
setTimeout(()=>{
resolve(1);
},1000)
})
}
function doSecondThing(res){
return new Promise(function(resolve,reject){
setTimeout(()=>{
resolve(res + 1);
},1000)
})
}
function doThirdThing(res){
return new Promise(function(resolve,reject){
setTimeout(()=>{
resolve(res + 2);
},1000)
})
}
promiseFactories = [doFirstThing, doSecondThing, doThirdThing];
function executeSequentially(promiseFactories) {
var result = Promise.resolve(); // this is the most problematic line
promiseFactories.forEach(function (promiseFactory) {
result = result.then(promiseFactory);// what is happening here ?
});
return result;
}
executeSequentially(promiseFactories)
我明白 promise 会在创建后立即执行。出于某种原因,我无法理解执行流程。特别是下面这一行:
var result = Promise.resolve()//and empty promise is created.
如果有人能帮助我理解如何在空承诺的 'then' 方法中调用 promiseFactory 方法使其按顺序执行,就像这样。还是因为 forEach 循环?
result = result.then(promiseFactory);
我尝试用 'map' 函数替换 'forEach',但仍然产生了相同的结果。即,按顺序执行的方法。
另外,值是如何从一个链式函数传递到另一个函数的?
任何帮助或 article/blog 非常感谢。
如果您想要这样的行为,始终建议使用 Promise.all
:
function doFirstThing() {
return new Promise(function(resolve, reject) {
setTimeout(() => {
resolve(1);
}, 1000)
})
}
function doSecondThing(res) {
return new Promise(function(resolve, reject) {
setTimeout(() => {
resolve(res + 1);
}, 1000)
})
}
function doThirdThing(res) {
return new Promise(function(resolve, reject) {
setTimeout(() => {
resolve(res + 2);
}, 1000)
})
}
let promiseFactories = [doFirstThing(2), doSecondThing(1), doThirdThing(3)];
Promise.all(promiseFactories)
.then(data => {
console.log("completed all promises", data);
})
至运行依次为:
function doFirstThing() {
return new Promise(function(resolve, reject) {
setTimeout(() => {
resolve(1);
}, 1000)
})
}
function doSecondThing(res) {
return new Promise(function(resolve, reject) {
setTimeout(() => {
resolve(res + 1);
}, 3000)
})
}
function doThirdThing(res) {
return new Promise(function(resolve, reject) {
setTimeout(() => {
resolve(res + 2);
}, 5000)
})
}
promiseFactories = [doFirstThing, doSecondThing, doThirdThing];
function executeSequentially(promiseFactories) {
promiseFactories.forEach(function(promiseFactory) {
promiseFactory(1).then((data) => {
console.log(data)
});
});
}
executeSequentially(promiseFactories);
您可以将 Promise 想象成一个盒子,里面有执行。只要创建了承诺,就开始执行。要获得结果值,您必须打开盒子。您可以使用 then
作为它:
Promise.resolve(5).then(result => console.log(result)); // prints 5
如果你想要连锁承诺,你可以通过一个一个地打开盒子来实现:
Promise.resolve(5)
.then(result => Promise.resolve(result + 1))
.then(result => Promise.resolve(result * 2))
.then(result => console.log(result)); // prints 12
这种链接使执行同步(一个接一个)。
如果你想执行多个承诺异步(你不链接结果),你可以使用Promise.all
:
Promise.all([Promise.resolve(1), Promise.resolve(2), Promise.resolve(3)])
.then(result => console.log(result)); // prints [1,2,3]
你的情况:
Promise.all(promiseFactories).then(result => console.log(result));
如何使用 promise 的另一种选择是 await
他们:
(async ()=> {
var res1 = await Promise.resolve(5);
var res2 = await Promise.resolve(res1 + 1);
var res3 = await Promise.resolve(res2 * 2);
console.log(res3); // prints 12
})();
await
的工作方式类似于 then
- 它使异步执行变为 同步 .
你的情况:
async function executeSequentially(promiseFactories) {
for (const p of promiseFactories) {
const result = await p;
console.log(result);
}
}
注意: await
将值打包到开箱即用的 Promise 中:
var res1 = await 5; // same as await Promise.resolve(5)
executeSequentially
方法returns所有Promise一个接一个。它恰好遍历promiseFactory
,但它可以写成:
function executeSequentially(promiseFactories) {
return doFirstThing()
.then(() => doSecondThing())
.then(doThirdThing() );
}
一模一样。我们基本上是在返回一个 Promise。
但是,现在我们想要迭代 一组承诺。
迭代时,我们需要使用 then
将当前 Promise 附加到前一个 Promise。但是 forEach
不会在每次迭代中公开下一个 Promise - 或上一个 - 。然而,我们仍然需要它来将 Promise 一个接一个地链接起来。因此,result
'hack':
function executeSequentially(promiseFactories) {
var result = Promise.resolve(); /*We need a thing that keeps yelling
the previous promise in every iteration, so we can keep chaining.
This 'result' var is that thing. This is keeping a Promise in every
iteration that resolves when all the previous promises resolve
sequentially. Since we don't have a Promise in the array
previous to the first one, we fabricate one out of 'thin air'
with Promise.resolve() */
promiseFactories.forEach(function (promiseFactory) {
result = result.then(promiseFactory); /* Here result is update
with a new Promise, with is the result of chaining `result`
with the current one. Since `result` already had all the previous ones,
at the end, `result` will be a Promise that depends upon all the
Promises resolution.*/
});
return result;
}
现在,还有一个语法怪癖可能让您感到困惑:
result = result.then(promiseFactory);
这一行与下面的几乎相同:
result = result.then(resolvedValue => promiseFactory(resolvedValue));
Please if somebody can help me understand how calling the promiseFactory method inside the 'then' method of the empty promise makes it execute sequentially, like so. Or is it because of the forEach loop ?
首先,promiseFactory
是一个非常糟糕的名字。方法应该这样写比较好:
function executeSequentially(promises) {
var result = Promise.resolve(); // this is the most problematic line
promises.forEach(function (currentPromise) {
result = result.then(currentPromise);// what is happening here ?
});
return result;
}
所以:
how calling the currentPromise
method inside the 'then' method of the empty promise makes it execute sequentially?
它使执行顺序执行,因为当您通过 then
将 Promise 附加到另一个时,它会顺序执行。是 then
的事情,它与我们正在迭代 Promises 的事实完全无关。在迭代之外使用普通的 Promise,它的工作原理几乎相同:
Promise.resolve() // fake Promises that resolves instanly
.then(fetchUsersFromDatabase) // a function that returns a Promise and takes
// like 1 second. It won't be called until the first one resolves
.then(processUsersData) // another function that takes input from the first, and
// do a lot of complex and asynchronous computations with data from the previous promise.
// it won't be called until `fetchUsersFromDatabase()` resolves, that's what
// `then()` does.
.then(sendDataToClient); // another function that will never be called until
// `processUsersData()` resolves
如果我们布置 foreach 循环,它将如下所示
function doFirstThing(){
return new Promise(function(resolve,reject){
setTimeout(()=>{
console.log(1);
resolve(1);
},1000)
})
}
function doSecondThing(res){
return new Promise(function(resolve,reject){
setTimeout(()=>{
console.log(2);
resolve(res + 1);
},2000)
})
}
function doThirdThing(res){
return new Promise(function(resolve,reject){
setTimeout(()=>{
console.log(3);
resolve(res + 2);
},3000)
})
}
Promise.resolve()
.then(doFirstThing())
.then(doSecondThing())
.then(doThirdThing());
I do understand that promises are executed as soon as they are created. For some reason i am not able to understand the flow of execution. Especially this following line:
var result = Promise.resolve()//and empty promise is created.
这只是为了掌握承诺链的起点。这是一个已经解决的承诺。为了更好地理解它,您可以使用您的承诺之一来获取如下所示的承诺链。
let promiseFactories= [doSecondThing, doThirdThing];
let result = doFirstThing();
promiseFactories.forEach(function (promiseFactory) {
result = result.then(promiseFactory);
});
这也行。
为了更清楚地理解承诺,我一直在阅读一些非常有趣的文章。我遇到了以下代码,它非常适合顺序执行承诺。但我无法理解它是如何工作的。
function doFirstThing(){
return new Promise(function(resolve,reject){
setTimeout(()=>{
resolve(1);
},1000)
})
}
function doSecondThing(res){
return new Promise(function(resolve,reject){
setTimeout(()=>{
resolve(res + 1);
},1000)
})
}
function doThirdThing(res){
return new Promise(function(resolve,reject){
setTimeout(()=>{
resolve(res + 2);
},1000)
})
}
promiseFactories = [doFirstThing, doSecondThing, doThirdThing];
function executeSequentially(promiseFactories) {
var result = Promise.resolve(); // this is the most problematic line
promiseFactories.forEach(function (promiseFactory) {
result = result.then(promiseFactory);// what is happening here ?
});
return result;
}
executeSequentially(promiseFactories)
我明白 promise 会在创建后立即执行。出于某种原因,我无法理解执行流程。特别是下面这一行:
var result = Promise.resolve()//and empty promise is created.
如果有人能帮助我理解如何在空承诺的 'then' 方法中调用 promiseFactory 方法使其按顺序执行,就像这样。还是因为 forEach 循环?
result = result.then(promiseFactory);
我尝试用 'map' 函数替换 'forEach',但仍然产生了相同的结果。即,按顺序执行的方法。 另外,值是如何从一个链式函数传递到另一个函数的?
任何帮助或 article/blog 非常感谢。
如果您想要这样的行为,始终建议使用 Promise.all
:
function doFirstThing() {
return new Promise(function(resolve, reject) {
setTimeout(() => {
resolve(1);
}, 1000)
})
}
function doSecondThing(res) {
return new Promise(function(resolve, reject) {
setTimeout(() => {
resolve(res + 1);
}, 1000)
})
}
function doThirdThing(res) {
return new Promise(function(resolve, reject) {
setTimeout(() => {
resolve(res + 2);
}, 1000)
})
}
let promiseFactories = [doFirstThing(2), doSecondThing(1), doThirdThing(3)];
Promise.all(promiseFactories)
.then(data => {
console.log("completed all promises", data);
})
至运行依次为:
function doFirstThing() {
return new Promise(function(resolve, reject) {
setTimeout(() => {
resolve(1);
}, 1000)
})
}
function doSecondThing(res) {
return new Promise(function(resolve, reject) {
setTimeout(() => {
resolve(res + 1);
}, 3000)
})
}
function doThirdThing(res) {
return new Promise(function(resolve, reject) {
setTimeout(() => {
resolve(res + 2);
}, 5000)
})
}
promiseFactories = [doFirstThing, doSecondThing, doThirdThing];
function executeSequentially(promiseFactories) {
promiseFactories.forEach(function(promiseFactory) {
promiseFactory(1).then((data) => {
console.log(data)
});
});
}
executeSequentially(promiseFactories);
您可以将 Promise 想象成一个盒子,里面有执行。只要创建了承诺,就开始执行。要获得结果值,您必须打开盒子。您可以使用 then
作为它:
Promise.resolve(5).then(result => console.log(result)); // prints 5
如果你想要连锁承诺,你可以通过一个一个地打开盒子来实现:
Promise.resolve(5)
.then(result => Promise.resolve(result + 1))
.then(result => Promise.resolve(result * 2))
.then(result => console.log(result)); // prints 12
这种链接使执行同步(一个接一个)。
如果你想执行多个承诺异步(你不链接结果),你可以使用Promise.all
:
Promise.all([Promise.resolve(1), Promise.resolve(2), Promise.resolve(3)])
.then(result => console.log(result)); // prints [1,2,3]
你的情况:
Promise.all(promiseFactories).then(result => console.log(result));
如何使用 promise 的另一种选择是 await
他们:
(async ()=> {
var res1 = await Promise.resolve(5);
var res2 = await Promise.resolve(res1 + 1);
var res3 = await Promise.resolve(res2 * 2);
console.log(res3); // prints 12
})();
await
的工作方式类似于 then
- 它使异步执行变为 同步 .
你的情况:
async function executeSequentially(promiseFactories) {
for (const p of promiseFactories) {
const result = await p;
console.log(result);
}
}
注意: await
将值打包到开箱即用的 Promise 中:
var res1 = await 5; // same as await Promise.resolve(5)
executeSequentially
方法returns所有Promise一个接一个。它恰好遍历promiseFactory
,但它可以写成:
function executeSequentially(promiseFactories) {
return doFirstThing()
.then(() => doSecondThing())
.then(doThirdThing() );
}
一模一样。我们基本上是在返回一个 Promise。
但是,现在我们想要迭代 一组承诺。
迭代时,我们需要使用 then
将当前 Promise 附加到前一个 Promise。但是 forEach
不会在每次迭代中公开下一个 Promise - 或上一个 - 。然而,我们仍然需要它来将 Promise 一个接一个地链接起来。因此,result
'hack':
function executeSequentially(promiseFactories) {
var result = Promise.resolve(); /*We need a thing that keeps yelling
the previous promise in every iteration, so we can keep chaining.
This 'result' var is that thing. This is keeping a Promise in every
iteration that resolves when all the previous promises resolve
sequentially. Since we don't have a Promise in the array
previous to the first one, we fabricate one out of 'thin air'
with Promise.resolve() */
promiseFactories.forEach(function (promiseFactory) {
result = result.then(promiseFactory); /* Here result is update
with a new Promise, with is the result of chaining `result`
with the current one. Since `result` already had all the previous ones,
at the end, `result` will be a Promise that depends upon all the
Promises resolution.*/
});
return result;
}
现在,还有一个语法怪癖可能让您感到困惑:
result = result.then(promiseFactory);
这一行与下面的几乎相同:
result = result.then(resolvedValue => promiseFactory(resolvedValue));
Please if somebody can help me understand how calling the promiseFactory method inside the 'then' method of the empty promise makes it execute sequentially, like so. Or is it because of the forEach loop ?
首先,promiseFactory
是一个非常糟糕的名字。方法应该这样写比较好:
function executeSequentially(promises) {
var result = Promise.resolve(); // this is the most problematic line
promises.forEach(function (currentPromise) {
result = result.then(currentPromise);// what is happening here ?
});
return result;
}
所以:
how calling the
currentPromise
method inside the 'then' method of the empty promise makes it execute sequentially?
它使执行顺序执行,因为当您通过 then
将 Promise 附加到另一个时,它会顺序执行。是 then
的事情,它与我们正在迭代 Promises 的事实完全无关。在迭代之外使用普通的 Promise,它的工作原理几乎相同:
Promise.resolve() // fake Promises that resolves instanly
.then(fetchUsersFromDatabase) // a function that returns a Promise and takes
// like 1 second. It won't be called until the first one resolves
.then(processUsersData) // another function that takes input from the first, and
// do a lot of complex and asynchronous computations with data from the previous promise.
// it won't be called until `fetchUsersFromDatabase()` resolves, that's what
// `then()` does.
.then(sendDataToClient); // another function that will never be called until
// `processUsersData()` resolves
如果我们布置 foreach 循环,它将如下所示
function doFirstThing(){
return new Promise(function(resolve,reject){
setTimeout(()=>{
console.log(1);
resolve(1);
},1000)
})
}
function doSecondThing(res){
return new Promise(function(resolve,reject){
setTimeout(()=>{
console.log(2);
resolve(res + 1);
},2000)
})
}
function doThirdThing(res){
return new Promise(function(resolve,reject){
setTimeout(()=>{
console.log(3);
resolve(res + 2);
},3000)
})
}
Promise.resolve()
.then(doFirstThing())
.then(doSecondThing())
.then(doThirdThing());
I do understand that promises are executed as soon as they are created. For some reason i am not able to understand the flow of execution. Especially this following line:
var result = Promise.resolve()//and empty promise is created.
这只是为了掌握承诺链的起点。这是一个已经解决的承诺。为了更好地理解它,您可以使用您的承诺之一来获取如下所示的承诺链。
let promiseFactories= [doSecondThing, doThirdThing];
let result = doFirstThing();
promiseFactories.forEach(function (promiseFactory) {
result = result.then(promiseFactory);
});
这也行。