Nodejs承诺所有不按预期运行

我有一系列我在testCard链接的testCard 。 这种方法需要一个stripe卡号码,从条带中获取令牌,然后与试图使用该卡执行购买的第三方API通信。 我需要通过循环访问一系列卡号来运行testCard 。 要做到这一点,我有一个controller对象的方法testAllCards采用数组的数组。 该数组存储在configuration文件中。

然后,我使用node cli.js testAllCards从命令行运行代码。

但是,当我运行它,我得到了所有大多数承诺已经解决之前testAllCards has been run 。 我显然在这里失去了一些东西,但似乎无法弄清楚它是什么。

cli.js

 const testAllCards = () => { return controller.testAllCards(config.get('CARD_NUMBERS')) .then((obj) => { console.log('testAllCards has been run'); }) .catch((e) => { console.log('testCards has been run with an error!'); const _err = new ErrHandler(e, eTopicName, eSnsSubject); _err.handle() .then(() => { console.log('Error has been sent with success to sns'); }); }); }; switch(process.argv[2]) { case 'testAllCards': testAllCards(); break; default: console.log('Please run with `testAllCards`'); 

controller.js

 //Tests response from API for different cards const testCard = (cardNum) => { return new Promise((resolve, reject) => { const expMonth = new Date().getMonth() + 1; const expYear = new Date().getFullYear() + 2; const cardObj = { cardNum: cardNum, expMonth: expMonth, expYear: expYear }; let apiCardItem = ''; return testRequestToApi('getStripeToken', 200, 299, cardObj) .then((cardItem) => { return testRequestToApi('postNewCard', 200, 299, JSON.parse(cardItem.body)); }) .then((apiCard) => { apiCardItem = apiCard.body; try { apiCardItem = JSON.parse(apiCardItem); } catch(e) { console.log(e); } return testRequestToApi('sampleAddToCart', 200, 299); }) .then(() => { return testRequestToApi('useFailingStripeCards', 400, 499, apiCardItem.id); }) .then(() => { return testRequestToApi('deleteCard', 200, 299, apiCardItem.id); }) .then(() => { resolve(); }) .catch((e) => { reject(e); }); }); }; //Loops through the card numbers and runs the test command against them Controller.testAllCards = (cardsArray) => { const items = cardsArray.map((cardNum) => { return testCard(cardNum); }); return Promise.all(items); }; module.exports = Controller; 

testing请求- api.js

 'use strict'; const checkStatus = require('./../utils/status-code-checker'); const formHeaders = require('./../utils/form-req-headers'); const request = require('request'); const expObj = {}; //@requestType {string} - defines which headers and function name to use //@item {object} - defines item that is being used expObj.testRequestToApi = (requestType, lowerLimit, upperLimit, item) => { return new Promise((resolve, reject) => { const reqOps = formHeaders[requestType](item); request(reqOps, (err, response, body) => { if (err) { const badRequest = { ErrorMessage: err, FuncName: requestType, InternalError: true }; return reject(badRequest); } if (!checkStatus.checkRangeStatusCode(response.statusCode, lowerLimit, upperLimit)) { console.log(JSON.stringify(body, null, 2)); // Set a bad Status error object let badStatus = { StatusCode: response.statusCode, ErrorMessage: body, FuncName: requestType, InternalError: false }; return reject(badStatus); } // console.log(response.headers); // console.log(body); const resObj = { headers: response.headers, body: body }; // console.log(`******** ${requestType} *********`); // console.log(resObj); // console.log('----------------------------------'); return resolve(resObj); }); }); }; module.exports = expObj; 

了解new Promise()只有在Promise基于callback的API时才需要使用,在cli.js中更改为request-promise并返回我的承诺解决了我的问题。 以这种方式正确维护执行stream程。

对以下文件的更改如下所示: cli.js

 const testAllCards = () => { return controller.testAllCards(config.get('CARD_NUMBERS')) .then((obj) => { console.log('testAllCards has been run'); }) .catch((e) => { console.log(e) console.log('testCards has been run with an error!'); const _err = new ErrHandler(e, eTopicName, eSnsSubject); return _err.handle() .then(() => { console.log('Error has been sent with success to sns'); }) .catch((e) => { console.log('Failed to publish to sns'); console.log(e); }); }); }; 

testing请求到API

 'use strict'; const checkStatus = require('./../utils/status-code-checker'); const formHeaders = require('./../utils/form-req-headers'); const rqp = require('request-promise'); const expObj = {}; //@requestType {string} - defines which headers and function name to use //@item {object} - defines item that is being used expObj.testRequestToApi = (requestType, lowerLimit, upperLimit, item) => { const reqOps = formHeaders[requestType](item); return rqp(reqOps) .then((response) => { if (!checkStatus.checkRangeStatusCode(response.statusCode, lowerLimit, upperLimit)) { console.log(JSON.stringify(response.body, null, 2)); // Set a bad Status error object return { StatusCode: response.statusCode, ErrorMessage: response.body, FuncName: requestType, InternalError: false }; } // console.log(response.headers); // console.log(response.body); const resObj = { headers: response.headers, body: response.body, previousItem: item }; // console.log(`******** ${requestType} *********`); // console.log(resObj); // console.log('----------------------------------'); return resObj; }) .catch((e) => { return { ErrorMessage: e, FuncName: requestType, InternalError: true }; }); }; module.exports = expObj; 

controller.js

 //Tests response from API for different cards Controller.testCard = (cardNum) => { const expMonth = new Date().getMonth() + 1; const expYear = new Date().getFullYear() + 2; const cardObj = { cardNum: cardNum, expMonth: expMonth, expYear: expYear }; let apiCardItem = ''; return testRequestToApi('getStripeToken', 200, 299, cardObj) .then((cardItem) => { return testRequestToApi('postNewCard', 200, 299, JSON.parse(cardItem.body)); }) .then((apiCard) => { apiCardItem = apiCard.body; try { apiCardItem = JSON.parse(apiCardItem); } catch(e) { console.log('Already a JSON object -----> Moving on'); } return testRequestToApi('sampleAddToCart', 200, 299); }) .then(() => testRequestToApi('useFailingStripeCards', 400, 499, apiCardItem.id)) .then(() => testRequestToApi('deleteCard', 200, 299, apiCardItem.id)); }; //Loops through the card numbers and runs the test command against them Controller.testAllCards = (cardsArray) => { return Promise.all(cardsArray.map((cardNum) => { return Controller.testCard(cardNum); })); }; module.exports = Controller; 

我重写了你的“testCard”函数(controller.js)

 //Tests response from API for different cards const testCard = (cardNum) => { return new Promise((resolve, reject) => { let apiCardItem = ''; const expDate = new Date(); const cardObj = { cardNum: cardNum, expMonth: expDate.getMonth() + 1, expYear: expDate.getFullYear() + 2 }; testRequestToApi('getStripeToken', 200, 299, cardObj) .then((cardItem) => testRequestToApi('postNewCard', 200, 299, JSON.parse(cardItem.body))) .then((apiCard) => { apiCardItem = apiCard.body; try { apiCardItem = JSON.parse(apiCardItem); } catch(e) { console.log(e); } return testRequestToApi('sampleAddToCart', 200, 299); }) .then(() => testRequestToApi('useFailingStripeCards', 400, 499, apiCardItem.id)) .then(() => testRequestToApi('deleteCard', 200, 299, apiCardItem.id)) .then(resolve) .catch(reject); }); };