我有一个promise函数,该函数会进行两次请求调用,并在第二次调用完成后解决。第二个解析调用也取决于第一个调用中的数据。但是在then函数中,变量返回值我为null。任何帮助将不胜感激。
编辑:secResp.body具有正确的数据,它不是null
const express = require('express');
const request = require('request');
const app = express();
const port = process.env.PORT || 5000;
// console.log that your server is up and running
app.listen(port, () => console.log(`Listening on port ${port}`));
app.get('/api/currentMatch/:name', function(req, res, next){
getPlayersInMatch(req.params.name).then(function(participants){
//this is null
console.log(participants);
}).catch(function (err) {
console.log(err);
});
})
function getPlayersInMatch(name){
return new Promise(function(resolve, reject){
request.get({
url: api_url
}, function(firstErr, firstResp, body){
if(firstResp.StatusCode != 200){
reject(firstErr);
}
var accountId = JSON.parse(firstResp.body).id;
request.get({
url: api_url2 + 'accountId=' + accountId
}, function(secErr, secResp, body){
if(secResp.StatusCode != 200){
reject(secErr);
}
//this is not null, this is an array
var participants = JSON.parse(secResp.body).participants;
resolve(participants);
});
});
});
}
答案 0 :(得分:1)
我将您的代码重写为request-promise。我发现您的代码的主要问题是它太复杂了。简化事情可以更轻松地发现您做错了什么。
const rp = require('request-promise')
const app = express();
const port = process.env.PORT || 5000;
// console.log that your server is up and running
app.listen(port, () => console.log(`Listening on port ${port}`));
app.get('/api/currentMatch/:name', function(req, res, next){
getPlayersInMatch(req.params.name)
.then(console.log)
.catch(console.error)
})
const getPlayersInMatch = async name => {
const id = await rp(api_url)
.then(res => JSON.parse(res.body).id)
const participants = await rp(api_url2 + 'accountId=' + accountId)
.then(res => JSON.parse(res.body).participants)
return { id, participants }
}
答案 1 :(得分:0)
<p>Enter in how many fingers (between 0 and 5) you are holding up: </p>
<p>
<input id="fingersInput" type="text">
<button id="fingersSubmit">Guess!</button>
</p>
<div id="fingers-game-v2"></div>
<p id="computer-guess-results"></p>
<script type="text/javascript">
var numberOfFingers = document.getElementById("fingersInput").value;
var fingersText = "";
var correctGuesses = 0;
document.getElementById("fingersSubmit").onclick = function ()
{
i = 0;
while (i < 5)
{
var computerGuess = Math.floor((Math.random()*5)+1);
fingersText += "<p>" + computerGuess + "</p>";
if (computerGuess == numberOfFingers)
{
var correctGuesses = correctGuesses + 1;
}
i++;
}
document.getElementById("fingers-game-v2").innerHTML = fingersText;
document.getElementById("computer-guess-results").innerHTML = "<h3>" + "Number of times the computer guessed correctly: " + "</h3>" + correctGuesses;
}
尝试一下。
一个,应该返回请求结果或对象。 第二,您应该使用async await,因为它不等待异步回调中的数据请求。
答案 2 :(得分:0)
在您的代码中,很难找出哪个步骤出错。
我认为最好将请求模块包装为:
/**
* Mapping knowing error_code
* @param {Number} error_code
* @param {String} msg
*/
function error_def(error_code, msg) {
let status, message;
switch(error_code){
case 400:
case 401:
case 402:
case 403:
case 1000:
case 1001:
case 1002:
case 1003:
case 1005:
status = error_code;
message = msg;
break;
default:
status = 2000;
message = 'Undefined Error'
}
return {status: status, msg: message};
}
/**
* Generate error message
* @param {String} tag
* @param {Number} error_code
* @param {String} msg
*/
function gen_error_func(tag = null) {
return function(error_code, msg = null) {
return {tag: tag, error_message: error_def(error_code, msg)}
}
}
/**
* Wrap the request and return interesting keys
* @param {String} tag
* @param {Object} req_opt
* @param {Array} interesting_resp
* @return {Object}
*/
function req_wrap(tag = null, req_opt, interesting_resp = null){
return new Promise((resolve, reject) => {
let gen_error = gen_error_func(tag)
if (!req_opt.url) {
reject(gen_error(1000, 'missing url'));
}
let option = {
url: req_opt.url,
method: (req_opt.method)? req_opt.method: 'GET',
}
request(option, function(error, response, body) {
if(error) {
reject(gen_error(1001, error));
return;
}
if (!response) {
reject(gen_error(1005, 'response is undefine, maybe wrong url!'))
return;
}
if (response.statusCode >= 400) {
//http level error
reject(gen_error(response.statusCode, body));
}else {
let result = {};
let body_json;
try {
body_json = JSON.parse(body);
}catch(e) {
reject(gen_error(1002, `Unknow response: ${body}`))
}
if (interesting_resp) {
interesting_resp.map(key => {
if (body_json[key] == undefined) {
reject(gen_error(1003, `In ${body_json}, undefined ${key}`))
return;
}
result[key] = body_json[key];
})
}else {
result = body_json;
}
resolve(result);
}
})
})
}
注意:在req_wrap中,如果无法在 interesting_resp 中找到响应键(未定义或为null),该函数将拒绝。有必要检查您要求的服务器规格!
您可以重写代码:
function getPlayersInMatch(name){
return new Promise(function(resolve, reject){
req_wrap('first_conn', {url: api_url}, ['id']).then(result => {
req_wrap('second_conn', {url: api_url2 + 'accountId=' + result.id}, ['participants']).then(result => {
resolve(result.participants)
}).catch(error => {
reject(error)
})
}).catch(error => {
reject(error)
})
});
}
现在更清楚地检查哪一步是错误的。