生成一个保证按顺序运行的数组

时间:2019-08-05 06:10:54

标签: javascript es6-promise

我正在尝试生成一个Promises数组以按顺序运行。我已经看到了很多有关此的技巧,但是无法在我的用例中运行它。

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))
}

有什么提示吗?这只是拒绝,我不明白为什么

3 个答案:

答案 0 :(得分:2)

当画布可用于所有子元素时,您似乎想解决主要承诺。您可以为此使用Promise.All()

还应注意,querySelectorAll不会返回您可以调用.map的任何内容。您将必须根据querySelectorAll返回的值(即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());
  })
}

答案 1 :(得分:1)

RunPython(migration_number=12, forward_code, reverse_code) 是一个NodeList,而NodeLists没有containers方法,这就是代码抛出错误的原因。

由于.map已经返回了Promise,因此无需再次使用Promise构造函数 processIcon也已经返回了Promise,因此在任何地方都不需要任何Promise构造函数(请参见What is the explicit promise construction antipattern and how do I avoid it?

如果可能的话,只需html2canvas循环中的每次调用await。因为for也返回了Promise,并且您要等待,所以也返回它(或uploadFromCanvas):

await

答案 2 :(得分:0)

根据您的问题,您可以使用Q module模块

您需要获取一个空数组并将promise推入其中,然后只需在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个州。一种是成功,一种是失败。

成功=> 状态 ===“已实现”,:“无论您的诺言回报多少”

失败=> 状态 ==='已拒绝',原因:“无论您提出了什么承诺”

在这种情况下,您会有许多成功和失败的承诺。

第二种方法是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被拒绝,则不再有任何Promise出现,突然您在Promise.all()中得到了Promise拒绝状态。

Promise.all(promiseHolder)
  .then((results) => {
    return results;
  })
  .catch((err) => {
    console.log('Promise will reject here', err);
    throw err;
  });

我希望对您有所帮助,快乐编码:)