代码之家  ›  专栏  ›  技术社区  ›  John

将promise函数推送到数组。使用答应我。好的. 承诺很早就下定决心了

  •  0
  • John  · 技术社区  · 6 年前

    我是个新手节点.js. 我对承诺函数和 Promise.all .

    情况如下。

    • var myNicePdfCreator={
           setting1: value1,
           setting2: value2,
           createPdf: function(customerId){
               return new Promise(function(resolve, reject){
                  dataBase.fetchForId(customerId).then(function(data){
                    somePdfLibrary.createPdf.then(function(path){
                     resolve(path);
                   },function(err){
                      //error creating pdf
                      reject(err);
                    });
                  },function(err){
                     //error fetching from db
                   reject(err);
               }
             })
           }
         }
      
    • 我有一个承诺功能,需要一个电子邮件地址和路径的pdf文件,然后发送一封电子邮件与附件pdf

      var myNiceMailSender={
      setting1: value1,
      setting2: value2,
      sendMail: function(email, path){
        return new Promise(function(resolve, reject){
           someMailLibrary.createMail(email, title, message, attachment).then(function(status){
          resolve(status);
         },function(err){
          reject(err);
         });
        });
      }
      }
      

    我想对数组中的每个对象都这样做(例如,为每个客户获取一份报告,然后通过电子邮件发送给他们)。我试图提出一个promise函数,它首先创建pdf,然后发送邮件并使用 forEach 循环将承诺推送到数组中,然后使用 答应我。好的 制作所有的PDF并发送邮件。但是无论我尝试什么,只要我把一个承诺推给一个数组,它在我使用之前就已经被解决了 答应我。好的 即使我只是尝试将两个promise函数中的一个推到数组中。

    如果我这样做;

     var promises=[];
        AllCustomers.forEach(customer){
         promises.push(myNicePdfCreator.createPdf(customer.id));
        });
    

    当我将PDF推送到数组时,会直接创建PDF。我甚至不需要打电话 答应我。好的 .

    有人能给我指出正确的方向吗?为什么我的承诺在我把它们推到阵列上时得到了解决?

    有没有更好的方法来创建PDF,然后通过电子邮件发送?

    谢谢您的帮助!

    0 回复  |  直到 6 年前
        1
  •  1
  •   David Vicente    6 年前

    我想你想要的是在你开始发送邮件之前把所有的PDF文件都整理好。正如有人已经说过的,当你呼唤一个承诺,除非你有一个。然后或等待它,它的执行不会等待。

    const promises=[];
    for(const customer of AllCustomers){
      promises.push(myNicePdfCreator.createPdf(customer.id));
    });
    Promise.all(promises).then((paths) => {
       // paths is going to have an array with the paths of all the pdfs already generated
    });
    

    用这个代码,在答应我。好的将等待所有PDF生成。所以在里面,你可以发邮件。

        2
  •  1
  •   TKoL    6 年前

    如果您想创建一系列未解决的、未处理的承诺,这些承诺为每个客户创建一个报告,然后通过电子邮件发送给该客户,它将如下所示:

    const pfuncs = AllCustomers.map(customer => {
      return async function() {
        const pdfPath = await myNicePdfCreator.createPdf(customer.id);
        const status = await myNiceMailSendor.sendMail(customer.email, pdfPath);
        return {status, pdfPath};
      }
    })
    

    这将创建一个函数数组--“createPdf”请求尚未开始运行,它正在等待您调用数组中的每个函数。

    当你准备好发送请求时,你会

    const results = await Promise.all(pfuncs.map(f => f()));
    

    现在是一个数组 [{status: 200, pdfPath: ''} , {status: 200, pdfPath: ''}, ...]

        3
  •  1
  •   jtwalters    6 年前

    承诺一经宣布就执行。 如果你想“锁定”所有的承诺直到所有的承诺都被定义,你可以封装在一个函数中,在声明了所有的承诺之后,做一个循环来执行它。

    // Await "a" seconds to finish, reject if "a" o "b" are negative
    function myPromiseFunction(a, b) {
        return new Promise((res, rej) => {
            setTimeout(() => {
                if (a < 0 || b < 0) {
                    rej(0);
                } else {
                    res(a+b);
                }
            }, a * 1000);
        })
    }
    
    (() => {
        let someData = [{a:2,b:2}, {a:10, b:4}];
    
        // Generate promises in functions
        let myPromises = someData.map((v) => {
            return () => myPromiseFunction(v.a, v.b);
        });
    
        // Execute all
        myPromises = myPromises.map((promise) => promise());
    
        // ...
    })();
    

    这个 Promise.all 函数只等待所有的承诺完成这个过程,否则任何承诺都会被拒绝。例如:

    所有的承诺都是好的:

    // Await "a" seconds to finish, reject if "a" o "b" are negative
    function myPromiseFunction(a, b) {
        return new Promise((res, rej) => {
            setTimeout(() => {
                if (a < 0 || b < 0) {
                    rej(0);
                } else {
                    res(a+b);
                }
            }, a * 1000);
        })
    }
    
    (() => {
        let someData = [{a:2,b:2}, {a:10, b:4}];
    
        // Generate promises in functions
        let myPromises = someData.map((v) => {
            return () => myPromiseFunction(v.a, v.b);
        });
    
        // Execute all
        myPromises = myPromises.map((promise) => promise());
    
        // Await all
        Promise.all(myPromises).then(res => {
            console.log(res, myPromises);
        }).catch(err => {
            console.log(err, myPromises);
        });
    })();
    

    您将打印 console.log 在里面 then 会是这样的:

    // res: [ 4, 14 ]
    // myPromises: [ Promise { 4 }, Promise { 14 } ]
    

    let someData = [{a:10,b:2}, {a:4, b:-4}, {a:2, b:4}];
    

    第二个承诺将被负值拒绝,但第一个承诺不会解决(10秒后结束),因此捕获的输出将为:

    // err: 0 (this is the error of the first rejected promise)
    // myPromises: [ 
    //     Promise { <pending> }, // The rejected promise will not stop the pendings
    //     Promise { <rejected> 0 }, // The rejected promise
    //     Promise { 6 }, // A "resolved" or maybe "pending"
    // ]