我目前正在完成编码挑战,并决定我希望更多的承诺练习,所以我将我的功能转换为承诺。这对第一个很好,但是当我添加第二个承诺时,我发现了一些我没想到的东西。这段代码:
// standard code provided for coding challenge
process.stdin.resume();
process.stdin.setEncoding('ascii');
var input_stdin = "";
var input_stdin_array = "";
var input_currentline = 0;
process.stdin.on('data', function (data) {
input_stdin += data;
});
process.stdin.on('end', function () {
input_stdin_array = input_stdin.split("\n");
main();
});
function readLine() {
return input_stdin_array[input_currentline++];
}
function main() {
var arr = [];
for(arr_i = 0; arr_i < 6; arr_i++){
arr[arr_i] = readLine().split(' ');
arr[arr_i] = arr[arr_i].map(Number);
}
// My code
let x = 0,
y = 0,
temp = 0,
answer = 0;
/* let incrementXY = new Promise((resolve, reject) => {
if(x < arr[0].length - 2) {
x += 1;
} else {
y += 1;
x = 0;
}
setTimeout(function(){
resolve(console.log("x is: " + x + " and y is: " + y));
}, 250);
});*/
// function returns total of each hourglass shape
let getHourGlass = new Promise((resolve, reject) => {
for(j = 0; j <= 2; j++) {
if(j === 0) {
temp = arr[y][x];
} else {
temp += arr[y][x + j];
}
if(j === 1) {
temp += arr[y + 1][x + 1];
}
temp += arr[y + 2][x + j];
}
setTimeout(function(){
resolve(temp);
}, 250);
});
getHourGlass.then(() => {
console.log("Temp is " + temp);
});
记录临时变量的预期值7。
然而,当我取消注释incrementXY
承诺代码时,即使我根本没有实现它,突然记录的temp
的值从7变为4.鉴于该功能确实如此甚至没有引用temp变量,这怎么可能?此外,当我将incrementXY
转换为函数时,只有当它被创建为一个承诺时才会发生这种情况。
如果它有用,那么当前输入是带有这些数据的2D数组:
1 1 1 0 0 0
0 1 0 0 0 0
1 1 1 0 0 0
0 0 2 4 4 0
0 0 0 2 0 0
0 0 1 2 4 0
我应该解释的另一件事是我使用的是HackerRank沙箱,所以它可能是他们环境的一些怪癖,但我的预感告诉我它可能是别的东西。
我可以转换承诺中的所有代码,但我认为这必须是使用承诺的某种怪癖,如果有人可以向我解释发生了什么,我会非常感激所以我可以感觉更自信,能够在将来正确使用它们而不会发生奇怪的事情。
答案 0 :(得分:0)
回答这部分
然而,当我取消注释
incrementXY
承诺代码时,即使我根本没有实现它,突然记录的temp
值从7变为4.鉴于函数不均匀参考temp
变量,这怎么可能?
变量temp
取决于在同一范围x
和y
中定义的内容。传递给Promise
构造函数的执行函数会更改影响temp
值的变量。
let a = 0
const promise = new Promise(resolve => {
console.log(`Creating a promise: ${a}`)
a++
setTimeout(resolve, 1000)
})
console.log(`Promise created: ${a}`)
a++
promise.then(() => console.log(`Promise resolved: ${a}`))
所以你的问题不是承诺本身,而是共享的可变状态。
所以我将我的功能转换为承诺
这没有多大意义。首先,我不明白为什么你的代码需要Promise。在您运行此代码时,您似乎拥有所有可用值。
然后Promises和Functions不可互换。可以认为Promise是一个值,可以在以后的某个时间使用。它没有行动或操作的概念。它是执行函数,您将传递给执行所有脏工作的promise构造函数。
但如果你想玩承诺你可以做这样的事情
const delay = fn => timeout =>
new Promise(resolve => setTimeout(() => resolve(fn()), timeout))
/* do not use shared mutable state
let x = 0,
y = 1,
temp = 0;
*/
// promises are values (not functions)
const calculatingXY = delay(() => ({x: 1, y: 2}))(250)
calculatingXY.then(({x, y}) => console.log(`Value of x is ${x}, value of y is ${y}`))
// sum x and y after 500 ms timeout
const calculatingSum = calculatingXY
.then(
({x, y}) => delay(() => x + y)(500)
)
Promise.all([calculatingXY, calculatingSum])
.then(
([{x,y}, z]) => console.log(`${x} + ${y} = ${z}`)
)
.catch(e => console.log(e))