按顺序生成 运行 的承诺数组
Generate an array of promises to run sequentially
我正在尝试按顺序为 运行 生成一组 Promise。我已经看到很多关于此的提示,但在我的用例中无法达到 运行。
export default function generateIcons(){
return new Promise((resolve, reject) => {
const containers = document.querySelectorAll('.html2CanvasTarget')
const promises = containers.map(child => processIcon(child))
promises.reduce((p, fn) => p.then(fn), Promise.resolve())
resolve()
})
}
function processIcon(child){
return new Promise((resolve, reject) => html2canvas(child).
then(canvas => uploadFromCanvas(canvas,
child.childNodes[0].className.split(' ')[1] + '.png'))
.then(resolve).catch(reject))
}
有什么建议吗?这只是拒绝,我不明白为什么
containers
是一个 NodeList,而 NodeList 没有 .map
方法,这就是您的代码抛出错误的原因。
因为 processIcon
已经 return 是一个 Promise,所以没有必要再次使用 Promise 构造函数 。 html2canvas
已经 return 也是一个 Promise,因此任何地方都不需要任何 Promise 构造函数(参见 What is the explicit promise construction antipattern and how do I avoid it?)
如果可能,在 for
循环中每次调用 await
。因为 uploadFromCanvas
return 也是一个 Promise,而您想等待它,return 它(或 await
它)也是如此:
export default async function generateIcons() {
const containers = document.querySelectorAll('.html2CanvasTarget');
for (const container of containers) {
await processIcon(container);
}
}
function processIcon(child) {
return html2canvas(child, {backgroundColor:null})
.then(canvas => uploadFromCanvas(canvas, child.className.split(' ')[1] + '.png'))
.catch(console.log);
}
根据你的问题,你可以使用 Q module 模块
你需要一个空数组并将promises推入其中,并在Q方法中传递这个数组(Q.allSettled
),看一个例子
const Q = require('q');
const promiseHolder = [];
for (let i = 0; i < 10; i += 1) {
promiseHolder.push('Your Promises');
}
Q.allSettled(promises)
.then((results) => {
results.forEach((result) => {
if (result.state === 'fulfilled') {
const value = result.value;
return value;
}
const reason = result.reason;
throw reason;
});
});
在Q.allSettled()
中的方法总是在.then()
中得到结果。有2个州。一个成功,一个失败。
成功 => 状态 === 'fulfilled', 值: 'Whatever your promise return'
失败 => 状态 === 'rejected', 原因: 'Whatever your promise thrown'
在这种情况下,您有许多成功和不成功的承诺。
第二种方法是 Promise.all()
做同样的事情,但问题是每当任何承诺被拒绝进一步的承诺从未被调用。
const promiseHolder = [];
for (let i = 0; i < 10; i += 1) {
promiseHolder.push('Your Promises');
}
Promise.all(promiseHolder)
.then((results) => {
return results;
})
.catch((err) => {
throw err;
});
在第二种方法 (Promise.all()
) 中,它包含从 for loop
推送的所有承诺。如果任何一个 promise rejected 没有更多的 promise 调用,突然你在 Promise.all()
中得到了 promise rejection 的状态。
Promise.all(promiseHolder)
.then((results) => {
return results;
})
.catch((err) => {
console.log('Promise will reject here', err);
throw err;
});
希望对您有所帮助,编码愉快:)
您似乎想在画布可用于所有子元素时解决主要承诺。您可以为此使用 Promise.All()。
还应注意 querySelectorAll
不会 return 任何您可以调用 .map
的东西。您将必须从 querySelectorAll
return 中创建一个数组 - 这是一个 NodeList。
export default function generateIcons(){
return new Promise((resolve, reject) => {
const containers = document.querySelectorAll('.html2CanvasTarget');
const promises = Array.from(containers).map(child => processIcon(child))
Promises.All(promises).then(() => resolve());
})
}
我正在尝试按顺序为 运行 生成一组 Promise。我已经看到很多关于此的提示,但在我的用例中无法达到 运行。
export default function generateIcons(){
return new Promise((resolve, reject) => {
const containers = document.querySelectorAll('.html2CanvasTarget')
const promises = containers.map(child => processIcon(child))
promises.reduce((p, fn) => p.then(fn), Promise.resolve())
resolve()
})
}
function processIcon(child){
return new Promise((resolve, reject) => html2canvas(child).
then(canvas => uploadFromCanvas(canvas,
child.childNodes[0].className.split(' ')[1] + '.png'))
.then(resolve).catch(reject))
}
有什么建议吗?这只是拒绝,我不明白为什么
containers
是一个 NodeList,而 NodeList 没有 .map
方法,这就是您的代码抛出错误的原因。
因为 processIcon
已经 return 是一个 Promise,所以没有必要再次使用 Promise 构造函数 。 html2canvas
已经 return 也是一个 Promise,因此任何地方都不需要任何 Promise 构造函数(参见 What is the explicit promise construction antipattern and how do I avoid it?)
如果可能,在 for
循环中每次调用 await
。因为 uploadFromCanvas
return 也是一个 Promise,而您想等待它,return 它(或 await
它)也是如此:
export default async function generateIcons() {
const containers = document.querySelectorAll('.html2CanvasTarget');
for (const container of containers) {
await processIcon(container);
}
}
function processIcon(child) {
return html2canvas(child, {backgroundColor:null})
.then(canvas => uploadFromCanvas(canvas, child.className.split(' ')[1] + '.png'))
.catch(console.log);
}
根据你的问题,你可以使用 Q module 模块
你需要一个空数组并将promises推入其中,并在Q方法中传递这个数组(Q.allSettled
),看一个例子
const Q = require('q');
const promiseHolder = [];
for (let i = 0; i < 10; i += 1) {
promiseHolder.push('Your Promises');
}
Q.allSettled(promises)
.then((results) => {
results.forEach((result) => {
if (result.state === 'fulfilled') {
const value = result.value;
return value;
}
const reason = result.reason;
throw reason;
});
});
在Q.allSettled()
中的方法总是在.then()
中得到结果。有2个州。一个成功,一个失败。
成功 => 状态 === 'fulfilled', 值: 'Whatever your promise return'
失败 => 状态 === 'rejected', 原因: 'Whatever your promise thrown'
在这种情况下,您有许多成功和不成功的承诺。
第二种方法是 Promise.all()
做同样的事情,但问题是每当任何承诺被拒绝进一步的承诺从未被调用。
const promiseHolder = [];
for (let i = 0; i < 10; i += 1) {
promiseHolder.push('Your Promises');
}
Promise.all(promiseHolder)
.then((results) => {
return results;
})
.catch((err) => {
throw err;
});
在第二种方法 (Promise.all()
) 中,它包含从 for loop
推送的所有承诺。如果任何一个 promise rejected 没有更多的 promise 调用,突然你在 Promise.all()
中得到了 promise rejection 的状态。
Promise.all(promiseHolder)
.then((results) => {
return results;
})
.catch((err) => {
console.log('Promise will reject here', err);
throw err;
});
希望对您有所帮助,编码愉快:)
您似乎想在画布可用于所有子元素时解决主要承诺。您可以为此使用 Promise.All()。
还应注意 querySelectorAll
不会 return 任何您可以调用 .map
的东西。您将必须从 querySelectorAll
return 中创建一个数组 - 这是一个 NodeList。
export default function generateIcons(){
return new Promise((resolve, reject) => {
const containers = document.querySelectorAll('.html2CanvasTarget');
const promises = Array.from(containers).map(child => processIcon(child))
Promises.All(promises).then(() => resolve());
})
}