Ich habe eine Reihe von Versprechen, die ich in testCard
verkettet habe. Diese Methode benötigt eine stripe
Kartennummer, holt das Token von stripe und spricht dann mit einer API eines Drittanbieters, die versucht, Einkäufe mit dieser Karte durchzuführen. Ich brauche testCard
durch Schleifen durch ein Array von Kartennummern. Um dies zu tun, habe ich ein controller
Objekt mit einer Methode testAllCards
, die das Array von Zahlen übernimmt. Das Array wird in einer Konfigurationsdatei gespeichert.Nodejs versprechen alle nicht wie erwartet laufen
Ich führe dann den Code von der Befehlszeile mit node cli.js testAllCards
.
Allerdings, wenn ich es ausführen, bekomme ich testAllCards has been run
, bevor alle die meisten Versprechen gelöst haben. Ich vermisse hier offensichtlich etwas, kann aber nicht herausfinden, was es ist.
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;
Test-Anfrage-to-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;
Dies ist das [Explizite Versprechen Konstruktion Anti-Muster] (https: // stackoverflow.com/questions/23803743/was-ist-die-explizite-versprechen-konstruktion-antipattern-und-wie-do-i-vermeiden-es). Dies ist das erste, was Sie beheben sollten. 'new Promise()' wird nur immer benötigt, wenn Sie eine Callback-basierte API promoten, die Sie nicht sind. In diesem Fall sollten Sie von "request" zu "request-promise" wechseln (https://github.com/request/request-promise). – Tomalak
Das nächste, was Sie beheben sollten, ist Ihre Abhängigkeit von einer äußeren Scope-Variable ('apiCardItem' in diesem Fall), die den asynchronen Zustand enthält. Die Rückgabewerte von Ihren Versprechungshandlern sollten Operationsergebnisse enthalten. – Tomalak
Danke @Tomalak. Ihre Hinweise haben geholfen, das Problem zu lösen. – hyprstack