使NodeJS Promise解析以等待所有处理完成

时间:2018-08-10 19:35:15

标签: javascript node.js promise

我正在使用util.promisify将Gmail API调用转换为承诺。

<?php
 error_reporting(E_ALL);
 set_time_limit(0);

 date_default_timezone_set('Europe/London');
 set_include_path(get_include_path() . PATH_SEPARATOR . 'lib/PHPExcel/');

 require_once 'lib/PHPExcel/PHPExcel/IOFactory.php';
 $fileType = 'Excel2007';
 $fileName = 'see.xlsx';

 // Read the file
 $objReader = PHPExcel_IOFactory::createReader($fileType);
 $objPHPExcel = $objReader->load($fileName);

 // Change the file
 $objPHPExcel->setActiveSheetIndex(0)
    ->setCellValue('A1', 'Hello')
    ->setCellValue('B1', 'World!');

 // Write the file
 $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, $fileType);
 $objWriter->save($fileName);

 ?>

这是上面的承诺返回函数调用的代码

async function listHistory(id, nextId, auth) {
  logger.info("Pulling all changes after historyId: " + id);

  let gmail = google.gmail('v1');

  let list = util.promisify(gmail.users.history.list);

  return list({
    auth: auth,
    userId: 'me',
    startHistoryId: id
  }).then(function(response) {

    if(typeof response !== "undefined") {
        if(typeof response !== "undefined") {
            if(typeof response.data === "object") {
                if(typeof response.data.history === "object") {
                    response.data.history.forEach(function(history) {
                        if(typeof history.messages === "object") {
                          history.messages.forEach(function(message) {
                            getMessage(message.id, auth); // >>> This is a network call
                          });
                        }
                    });
                }         
            }
        }
    }

  }).catch(exception => {
    logger.info("Pulling changes for historyId: " + id + " returned error: " + exception);
  });
}

即使在所有处理都完成之前,即forEach循环网络调用之前,承诺也已解决。我只能在foreach循环中的所有网络调用完成后才能解析它吗?

谢谢。

1 个答案:

答案 0 :(得分:0)

您可以使用Promise.all并将所有网络调用映射到一个数组中。更改一些代码作为示例

async function listHistory(id, nextId, auth) {
    logger.info("Pulling all changes after historyId: " + id);

    let gmail = google.gmail('v1');

    let list = util.promisify(gmail.users.history.list);

    //you can await the list.
    try {
        const response = await list({
            auth: auth,
            userId: 'me',
            startHistoryId: id
        })
        const getMessagePromiseArray = [];
        if (response && response.data && Array.isArray(response.data.history)) {
            response.data.history.forEach(function (history) {
                if (Array.isArray(history.messages)) {
                    history.messages.forEach(function (message) {
                        getMessagePromiseArray.push(getMessage(message.id, auth)); // >>> This is a network call
                    });
                }
            });
        }
        return Promise.all(getMessagePromiseArray);
    } catch (exception) {
        logger.info("Pulling changes for historyId: " + id + " returned error: " + exception);
    };
}