在等待 json 响应时未兑现诺言
Uncaught in promise while waiting for json response
我第一次在 JS 中实现 Promises,并且在 运行 下面的代码中未捕获到控制台日志中的 Promise 异常。
function data_present() {
return new Promise((resolve, reject) => {
fetch(api)
.then(response => response.json())
.then(message => {
console.log(message)
if(message && Object.keys(message).length != 0) {
resolve()
}
else {
reject()
}
})
})
}
我正在如下处理主函数中 promise return 值的结果,但尚未收到未捕获的 promise 消息:
function main() {
data_present().then(() => {
load_graph()
}).catch(() => {
data_present()
})
}
data_present() 背后的逻辑是等到我们在 API 端点得到一个非空的 JSON 响应,如果 JSON 则继续轮询它响应为空。
我得到的异常如下:
Uncaught (in promise) undefined
(anonymous) @ index.js:34
Promise.then (async)
(anonymous) @ index.js:29
data_present @ index.js:26
(anonymous) @ index.js:56
Promise.catch (async)
getParametersData @ index.js:55
onclick @ (index):92
也fetch
已经returns一个承诺。所以你不应该再包装它(我在我的例子中包括了这个)。错误来自对函数的第二次调用,如下面的第二个 catch 块所述
function data_present() {
return fetch(api)
.then(response => response.json())
.then(message => {
console.log(message)
if (!message || Object.keys(message).length === 0) {
throw new Error('something went wrong');
}
})
}
function main() {
data_present()
.then(() => {
load_graph()
}).catch(() => {
return data_present() // the promise which is returned here was not caught in your example
})
.catch(() => {
// another error
})
}
您可能会考虑使用一个函数来获取、解析和 return 来自 API 的 JSON(无需将您的 fetch
包装在一个 promise 中因为它已经 returns 一个),并使用您的轮询功能来检查 returned 数据。如果正确则调用一个函数,否则再次轮询 getData
。如果有一个 API 错误记录,而不是。
我这里用的是async/await
,原理是一样的
// Simulates an API
// If the random number is a modulo of 5 set data
// to an object with a key/value pair, otherwise
// it set it to an empty object. If the random number
// is a modulo of 9 send an error, otherwise send the data.
function mockFetch() {
return new Promise((res, rej) => {
const rnd = Math.floor(Math.random() * 20);
const data = rnd % 5 === 0 ? { name: 'Bob' } : {};
setTimeout(() => {
if (rnd % 9 === 0) rej('Connection error');
res(JSON.stringify(data));
}, 2000);
});
}
// `getData` simply gets a response from the API and parses it.
// I had to use JSON.parse here rather that await response.json()
// because I'm not using the actual fetch API.
async function getData() {
const response = await mockFetch();
return JSON.parse(response);
}
// The `poll` function does all the heavy-lifting
// first we initialise `count`
async function poll(count = 1) {
console.log(`Polling ${count}`);
// Try and get some data. If it's not an empty object
// log the name (or in your case call loadGraph),
// otherwise poll the API again after two seconds.
// We wrap everything in a `try/catch`.
try {
const data = await getData();
if (data && data.name) {
console.log(data.name); // loadGraph
} else {
setTimeout(poll, 2000, ++count);
}
// If the API sends an error log that instead
// and poll again after five seconds
} catch (err) {
console.log(`${err}. Polling again in 5 seconds.`);
setTimeout(poll, 5000, 1);
}
}
poll();
这是版本 :
function mockFetch() {
return new Promise((res, rej) => {
const rnd = Math.floor(Math.random() * 20);
const data = rnd % 5 === 0 ? { name: 'Bob' } : {};
setTimeout(() => {
if (rnd % 9 === 0) rej('Connection error');
res(JSON.stringify(data));
}, 2000);
});
}
async function getData() {
const response = await mockFetch();
return JSON.parse(response);
}
async function delay(time) {
return new Promise(res => setTimeout(res, time));
}
async function poll(count = 1) {
do {
console.log(`Polling ${count}`);
try {
const data = await getData();
if (data && data.name) return data;
await delay(2000);
} catch (err) {
console.log(`${err}. Polling again in 5 seconds.`);
await delay(5000);
}
++count;
} while (count < 10);
console.log(`Reached poll limit - ${count}.`);
return false;
}
async function main() {
console.log('First');
console.log(await poll());
console.log('Second');
}
main();
我第一次在 JS 中实现 Promises,并且在 运行 下面的代码中未捕获到控制台日志中的 Promise 异常。
function data_present() {
return new Promise((resolve, reject) => {
fetch(api)
.then(response => response.json())
.then(message => {
console.log(message)
if(message && Object.keys(message).length != 0) {
resolve()
}
else {
reject()
}
})
})
}
我正在如下处理主函数中 promise return 值的结果,但尚未收到未捕获的 promise 消息:
function main() {
data_present().then(() => {
load_graph()
}).catch(() => {
data_present()
})
}
data_present() 背后的逻辑是等到我们在 API 端点得到一个非空的 JSON 响应,如果 JSON 则继续轮询它响应为空。
我得到的异常如下:
Uncaught (in promise) undefined
(anonymous) @ index.js:34
Promise.then (async)
(anonymous) @ index.js:29
data_present @ index.js:26
(anonymous) @ index.js:56
Promise.catch (async)
getParametersData @ index.js:55
onclick @ (index):92
也fetch
已经returns一个承诺。所以你不应该再包装它(我在我的例子中包括了这个)。错误来自对函数的第二次调用,如下面的第二个 catch 块所述
function data_present() {
return fetch(api)
.then(response => response.json())
.then(message => {
console.log(message)
if (!message || Object.keys(message).length === 0) {
throw new Error('something went wrong');
}
})
}
function main() {
data_present()
.then(() => {
load_graph()
}).catch(() => {
return data_present() // the promise which is returned here was not caught in your example
})
.catch(() => {
// another error
})
}
您可能会考虑使用一个函数来获取、解析和 return 来自 API 的 JSON(无需将您的 fetch
包装在一个 promise 中因为它已经 returns 一个),并使用您的轮询功能来检查 returned 数据。如果正确则调用一个函数,否则再次轮询 getData
。如果有一个 API 错误记录,而不是。
我这里用的是async/await
,原理是一样的
// Simulates an API
// If the random number is a modulo of 5 set data
// to an object with a key/value pair, otherwise
// it set it to an empty object. If the random number
// is a modulo of 9 send an error, otherwise send the data.
function mockFetch() {
return new Promise((res, rej) => {
const rnd = Math.floor(Math.random() * 20);
const data = rnd % 5 === 0 ? { name: 'Bob' } : {};
setTimeout(() => {
if (rnd % 9 === 0) rej('Connection error');
res(JSON.stringify(data));
}, 2000);
});
}
// `getData` simply gets a response from the API and parses it.
// I had to use JSON.parse here rather that await response.json()
// because I'm not using the actual fetch API.
async function getData() {
const response = await mockFetch();
return JSON.parse(response);
}
// The `poll` function does all the heavy-lifting
// first we initialise `count`
async function poll(count = 1) {
console.log(`Polling ${count}`);
// Try and get some data. If it's not an empty object
// log the name (or in your case call loadGraph),
// otherwise poll the API again after two seconds.
// We wrap everything in a `try/catch`.
try {
const data = await getData();
if (data && data.name) {
console.log(data.name); // loadGraph
} else {
setTimeout(poll, 2000, ++count);
}
// If the API sends an error log that instead
// and poll again after five seconds
} catch (err) {
console.log(`${err}. Polling again in 5 seconds.`);
setTimeout(poll, 5000, 1);
}
}
poll();
这是版本
function mockFetch() {
return new Promise((res, rej) => {
const rnd = Math.floor(Math.random() * 20);
const data = rnd % 5 === 0 ? { name: 'Bob' } : {};
setTimeout(() => {
if (rnd % 9 === 0) rej('Connection error');
res(JSON.stringify(data));
}, 2000);
});
}
async function getData() {
const response = await mockFetch();
return JSON.parse(response);
}
async function delay(time) {
return new Promise(res => setTimeout(res, time));
}
async function poll(count = 1) {
do {
console.log(`Polling ${count}`);
try {
const data = await getData();
if (data && data.name) return data;
await delay(2000);
} catch (err) {
console.log(`${err}. Polling again in 5 seconds.`);
await delay(5000);
}
++count;
} while (count < 10);
console.log(`Reached poll limit - ${count}.`);
return false;
}
async function main() {
console.log('First');
console.log(await poll());
console.log('Second');
}
main();