gpt4 book ai didi

javascript - 我是否很好地使用了 Promise?

转载 作者:太空宇宙 更新时间:2023-11-04 03:05:35 24 4
gpt4 key购买 nike

问题

我的问题是我希望我的代码执行以下操作:

  1. 提出初始请求
  2. 收到该请求的答案后,我会对其进行处理并再次发出一批请求
  3. 完成批处理并获得其所有响应后,我会编写一个文件
  4. 文件完成后,我会打印一条消息

我的前两个步骤是正确的,但我的程序没有按照我的预期执行最后两个步骤。

代码

这段代码试图举例说明我想要实现的目标。仅用promisejsonfile这是一个简单的应用程序,详细地代表了我的代码的架构,并且只要您安装了这两个库,它就能立即运行。

let jsonfile = require("jsonfile");
let Promise = require("promise");
let write = Promise.denodeify(jsonfile.writeFile);

let writeOutput = function(filename, content) {
return write(filename, content, {spaces: 4});
};

//Returns a random number each time it is invoked
//after a random period of time between 1s and 6s
let requestSimulator = function() {
return new Promise((fulfil, reject) => {
let randomNum = Math.random();
let wait = Math.floor((Math.random() * 6000) + 2000);
setTimeout(() => fulfil(randomNum), wait, randomNum);
});
};

//Returns an array of rounded numbers
let roundNumbers = function(someNumbers) {
let numbersArr = [];
let tmpNum;
for (let number of someNumbers) {
tmpNum = Math.floor(number);
console.log("Rounded " + number + " to " + tmpNum);
numbersArr.push(tmpNum);
}

return numbersArr;
};

//Receives an array of rounded numbers, and for each number
//makes a new request.
//It then sums the response with the given number.
let sumNumbersBatch = function(numbersArr) {
let promisesArray = [];

for (let number of numbersArr) {

let promise = new Promise((fulfil, reject) => {
requestSimulator()
.then(result => {
let newNum = number + result;
console.log("Summing " + number + " with " + result + "resultint in " + newNum);
fulfil(newNum);
});
});

promisesArray.push(promise);
}

return new Promise.all(promisesArray);
};

//Starts the process
let getData = function() {
return new Promise((fulfil, reject) => {
requestSimulator()
.then(number => fulfil([number, number * 2, number * 3]));
});
};

console.log("Starting program");
getData()
.then(roundNumbers)
.then(sumNumbersBatch)
.then(newNumbers => writeOutput("testFile.txt", newNumbers))
.then(console.log("Program finished"))
.catch(console.log);

运行后,您可以看到输出如下:

Starting program
Program finished
Rounded 0.20890058801647582 to 0
Rounded 0.41780117603295164 to 0
Rounded 0.6267017640494275 to 0
Summing 0 with 0.05537663551196226resultint in 0.05537663551196226
Summing 0 with 0.34853429001859215resultint in 0.34853429001859215
Summing 0 with 0.988336787994851resultint in 0.988336787994851

这是错误的!!!

Program finish 应该出现在最后,而不是第二!

问题:

所以现在我对我的代码有疑问:

  1. 我是否正确使用了 Promise.all ?
  2. 我是否能够很好地保证 write 功能?

此外,我愿意接受有关代码质量的建议!!!!

任何帮助和解释将不胜感激。

最佳答案

我已经重写了整个答案以匹配修改后的代码。我对“答案”的第一次尝试只不过是对第一个提供的代码似乎有问题的地方进行了扩展评论;所以什么也没有丢失。

你的大部分代码都是正确的,这一行实际上是“错误的”:

.then(console.log("Program finished"))

并且会让你感到困惑,因为它立即调用 console.log("Program finish") 并返回 undefined,因此 then 会转换为 .then(undefined)

应该是

.then(() => console.log("Program finished"))

并且Promise.all()前面应该有no new

<小时/>

尽管有一些事情可以改进,特别是您对延迟反模式的使用。这是在没有必要时,当您已经在该位置处理 promise 时手动创建延迟对象。比如这个:

//Starts the process
let getData = function() {
return new Promise((fulfil, reject) => {
requestSimulator()
.then(number => fulfil([number, number * 2, number * 3]));
});
};

更好

//Starts the process
let getData = function() {
return requestSimulator().then(number => [number, number * 2, number * 3]);
};

而在 requestSimulator 中,您需要创建一个 new Promise() 才能将 Promise 与 setTimeout() 一起使用。这是合适的。

let jsonfile = require("jsonfile");
let Promise = require("promise");
let write = Promise.denodeify(jsonfile.writeFile);

//OK, now this function has a purpose/additional value (formatting)
//and is not just forwarding the arguments
let writeOutput = function(filename, content) {
return write(filename, content, {spaces: 4});
};

//fine, a mock
let requestSimulator = function() {
return new Promise((fulfil, reject) => {
let randomNum = Math.random();
let wait = Math.floor((Math.random() * 6000) + 2000);
//there's no need/reason to pass `randomNum` to setTimeout as a third argument
setTimeout(() => fulfil(randomNum), wait);
});
};

//this can be shortened to, although it doesn't log anymore
let roundNumbers = function(someNumbers) {
return someNumbers.map(Math.floor);
};

//Receives an array of rounded numbers, and for each number
//makes a new request.
//It then sums the response with the given number.
let sumNumbersBatch = function(numbersArr) {
//this again can be achieved simpler by using `Array#map` instead of `for..of`
let promisesArray = numbersArr.map(number => {
return requestSimulator()
.then(result => result + number);
});

//no `new` here! Promise.all() is just a utility-function, no constructor.
return Promise.all(promisesArray);
};

//Starts the process
let getData = function() {
//removed the wrapping Promise.
return requestSimulator()
.then(number => [ number, number * 2, number * 3 ]);
};

console.log("Starting program");
getData()
.then(roundNumbers)
.then(sumNumbersBatch)
.then(newNumbers => writeOutput("testFile.txt", newNumbers))
//this executes `console.log()` immediately and passes the result (`undefined`) to `then()`
//.then(console.log("Program finished"))
//but `then()` needs a function:
.then(() => console.log("Program finished"))
//here you pass a reference to the function `console.log`, that's fine
.catch(console.log);

关于javascript - 我是否很好地使用了 Promise?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41894248/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com