我有一个简单的代码,提示用户输入,然后对输入进行操作。在代码的试运行中,出现错误: UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'node' of undefined
,但并非总是如此。我不明白为什么它有时仅会引发错误?
input-interface.js
'use strict';
const readline = require('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
module.exports = {
prompt: function prompt(question) {
return new Promise((resolve) => {
rl.setPrompt(question);
rl.prompt();
rl.once("line", resolve);
});
}
}
interactive-request-procedures.js
'use strict'
const input_interface = require('./input_interface');
const InteractiveRequestProcedures = Object.create(input_interface);
InteractiveRequestProcedures.createInputNode = async function createInputNode() {
return {
position: await this.prompt("Position? start(s), end(e), position(integer) > "),
value: await this.prompt("Value? > "),
};
}
InteractiveRequestProcedures.inputRemoveKey = async function inputRemoveKey() {
return await this.prompt("Remove Key? > ");
}
InteractiveRequestProcedures.requestProcedure = async function requestProcedure() {
const procedure = await this.prompt("Procedure? insert(i), delete(d) > ");
if (procedure === "i") {
return {
procedure,
node: await this.createInputNode(),
}
} else if (procedure === "d") {
return {
procedure,
node: await this.inputRemoveKey(),
}
} else {
console.log(`Invalid input '${procedure}': Please select again\n`);
await this.requestProcedure();
}
}
module.exports = InteractiveRequestProcedures;
main-program.js
UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'node' of undefined
所在的行在下面的代码中用注释突出显示。
'use strict';
const LinkedList = Object.create(require('./interactive-request-procedures'));
LinkedList.setup = function setup() {
this.lhead = -1;
this.last = -1;
this.free = -1;
this.key = [];
this.next = [];
this.prev = [];
this.listLength = 0;
this.input();
}
LinkedList.input = async function input() {
while(true) {
let input = await this.requestProcedure(); //UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'node' of undefined
let { position, value } = input.node;
if (input.procedure === "i") {
switch (position) {
case '1':
case 's':
this.prepend(value); // implementation details not shown
break;
case 'e':
case `${this.next.length}`:
this.append(value); // implementation details not shown
break;
default:
/* Check to see if position is an integer */
if ( (position ^ 0) === parseInt(position, 10) ) {
console.log(`Invalid input: Position ${position} is not an integer`);
continue;
}
/* Check to see if position exceeds list length */
if (position > this.listLength) {
console.log(`Invalid input: Position ${position} exceeds list length ${this.listLength}\nTry Again\n`);
continue;
}
this.insertAt(value, position); // implementation details not shown
}
}
if (input.procedure === 'd') this.deleteNode(input.node);
const resp = await this.prompt("Continue? y / n > ");
if (resp === "n")
break;
console.log("\n");
}
console.log(this.list);
}
LinkedList.setup();
试运行
我使用node main-program.js
me@myBook ~/main-program (master) $ node skip-list.js
Procedure? insert(i), delete(d) > aef
Invalid input 'aef': Please select again
Procedure? insert(i), delete(d) > i
Position? start(s), end(e), position(integer) > 2332
Value? > 23
(node:41451) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'node' of undefined
at Object.input (main-program.js:51:34)
at <anonymous>
at process._tickCallback (internal/process/next_tick.js:189:7)
(node:41451) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (reject
ion id: 1)
(node:41451) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
me@myBook ~/main-program (master) $ node skip-list.js
Procedure? insert(i), delete(d) > i
Position? start(s), end(e), position(integer) > 3232
Value? > 2
Invalid input: Position 3232 is not an integer
Procedure? insert(i), delete(d) > i
Position? start(s), end(e), position(integer) > 234
Value? > 34
Invalid input: Position 234 is not an integer
Procedure? insert(i), delete(d) > 244355
Invalid input '244355': Please select again
Procedure? insert(i), delete(d) > i
Position? start(s), end(e), position(integer) > 3232
Value? > 224
(node:41455) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'node' of undefined
at Object.input (main-program.js:51:34)
at <anonymous>
at process._tickCallback (internal/process/next_tick.js:189:7)
(node:41455) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (reject
ion id: 1)
(node:41455) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
Value? > 434
答案 0 :(得分:1)
我们需要处理错误,以防止发生此类异常
当我们使用异步等待时,我们需要使用“ try catch”块 当我们使用诺言时,我们需要使用'then and catch'块
try {
// positive case
} catch(error) {
// handle errors here
}
答案 1 :(得分:1)
此行中的异步操作:
let input = await this.requestProcedure();
失败,因此未设置input
变量。因此,当它继续执行下一行时:
let { position, value } = input.node;
您得到Cannot read property 'node' of undefined
,因为输入不包含值。
您应该在try catch中执行异步命令,以便可以看到错误的详细信息:
try {
let input = await this.requestProcedure();
// run the rest of your code
}
catch(error) {
// Do something with the error (e.g. log it, print it)
}
不幸的是,我们无法确定是什么原因导致了异步操作问题,但这就是您在问题中提到的错误的原因。这也将帮助您调试它。
答案 2 :(得分:1)
尽管您应始终在异步/等待代码周围使用try ... catch块,但这将无助于解决“为什么有时起作用而有时会失败?”的问题
您的问题出在以下代码段中:
} else {
console.log(`Invalid input '${procedure}': Please select again\n`);
await this.requestProcedure();
}
输入无效的输入后,此代码块将不提供该函数的返回值。
要重现您的问题:
要解决此问题,只需在最后一个其他地方返回即可:
} else {
console.log(`Invalid input '${procedure}': Please select again\n`);
return await this.requestProcedure();
}