小赖子的英国生活和资讯

ChatGPT 使用 Promise.All 重构/重写代码(并行发送请求)

阅读 桌面完整版

在我的一个项目中, 我有以下代码(Node/Javascript), 它(顺序)调用了一些 API. 这些 HTTPS 请求其实是可以并行完成的, 因为它们相互独立. 然后结果会被聚合到一个数组中.

我知道可以用Promise.all来把这些请求并行化, 我就问了ChatGPT怎么弄, 看看它是否能理解并给出正确的代码:

我先用英文问 ChatGPT-3.5: Rewrite the following Python code using the Promise.all to parallelize the requests:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
  let result = {
    "node": node,
    "time": new Date().toISOString(),
    "enabled_plugins": [],
    "disabled_plugins": [],
  };
  const pluginNames = Object.keys(plugins);
  for (let i = 0; i < pluginNames.length; ++ i) {
    const plugin = pluginNames[i];
    const api = plugins[plugin];
    const params = api.slice(1)[0];
    const succ = await callAPI(node, plugin, api[0], params);
    if (succ) {
      result["enabled_plugins"].push(plugin);
    } else {
      result["disabled_plugins"].push(plugin);
    }
  }
  let result = {
    "node": node,
    "time": new Date().toISOString(),
    "enabled_plugins": [],
    "disabled_plugins": [],
  };
  const pluginNames = Object.keys(plugins);
  for (let i = 0; i < pluginNames.length; ++ i) {
    const plugin = pluginNames[i];
    const api = plugins[plugin];
    const params = api.slice(1)[0];
    const succ = await callAPI(node, plugin, api[0], params);
    if (succ) {
      result["enabled_plugins"].push(plugin);
    } else {
      result["disabled_plugins"].push(plugin);
    }
  }

ChatGPT-3.5确实理解了代码并且我的用意, 给出了正确的结果, 并且ChatGPT还给出了代码解释.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
let result = {
  "node": node,
  "time": new Date().toISOString(),
  "enabled_plugins": [],
  "disabled_plugins": [],
};
 
const pluginNames = Object.keys(plugins);
const promises = [];
 
for (let i = 0; i < pluginNames.length; ++i) {
  const plugin = pluginNames[i];
  const api = plugins[plugin];
  const params = api.slice(1)[0];
 
  promises.push(callAPI(node, plugin, api[0], params));
}
 
const results = await Promise.all(promises);
 
results.forEach((succ, index) => {
  const plugin = pluginNames[index];
 
  if (succ) {
    result["enabled_plugins"].push(plugin);
  } else {
    result["disabled_plugins"].push(plugin);
  }
});
let result = {
  "node": node,
  "time": new Date().toISOString(),
  "enabled_plugins": [],
  "disabled_plugins": [],
};

const pluginNames = Object.keys(plugins);
const promises = [];

for (let i = 0; i < pluginNames.length; ++i) {
  const plugin = pluginNames[i];
  const api = plugins[plugin];
  const params = api.slice(1)[0];

  promises.push(callAPI(node, plugin, api[0], params));
}

const results = await Promise.all(promises);

results.forEach((succ, index) => {
  const plugin = pluginNames[index];

  if (succ) {
    result["enabled_plugins"].push(plugin);
  } else {
    result["disabled_plugins"].push(plugin);
  }
});

在重构后的代码中, 我们创建了一个数组promises, 并将每个callAPI的promise推入其中. 然后, 我们使用Promise.all同时执行所有的promise. 结果存储在results数组中, 然后使用forEach进行迭代. 在forEach循环内部, 我们可以通过succ访问每个API调用的结果, 通过pluginNames[index]访问相应的插件名称. 然后, 将结果推送到result对象的适当数组中.

ChatGPT-3.5 Refactors code using Promise.all

后来我又用中文问了一下, 不过这次我选择了ChatGPT-4 但是给出的代码并没有上面给的好.

以下是一个基于Promise.all的并行化版本的代码. 在这个版本中, 所有的插件都将同时进行API调用, 然后将结果放入enabled_plugins或disabled_plugins数组列表中.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
let result = {
    "node": node,
    "time": new Date().toISOString(),
    "enabled_plugins": [],
    "disabled_plugins": [],
};
 
const pluginNames = Object.keys(plugins);
const promises = pluginNames.map(plugin => {
    const api = plugins[plugin];
    const params = api.slice(1)[0];
    return callAPI(node, plugin, api[0], params)
        .then(succ => {
            if (succ) {
                result["enabled_plugins"].push(plugin);
            } else {
                result["disabled_plugins"].push(plugin);
            }
        });
});
 
await Promise.all(promises);
let result = {
    "node": node,
    "time": new Date().toISOString(),
    "enabled_plugins": [],
    "disabled_plugins": [],
};

const pluginNames = Object.keys(plugins);
const promises = pluginNames.map(plugin => {
    const api = plugins[plugin];
    const params = api.slice(1)[0];
    return callAPI(node, plugin, api[0], params)
        .then(succ => {
            if (succ) {
                result["enabled_plugins"].push(plugin);
            } else {
                result["disabled_plugins"].push(plugin);
            }
        });
});

await Promise.all(promises);

注意: 这个版本的代码可能会更快, 但它会使得enabled_plugins和disabled_plugins中的插件顺序不再是按照原始的plugins中的顺序. 如果顺序很重要的话, 那么你可能需要在Promise.all后对enabled_plugins和disabled_plugins重新排序.

此外, 由于这个版本的代码中的所有API调用都是并行的, 所以如果你有大量的插件, 你可能会在同一时间点对你的系统或网络产生大量的负载. 如果这是一个问题, 你可能需要考虑使用并发控制的方法来限制同时进行的API调用的数量.

ChatGPT-4给出的代码并没有ChatGPT-3.5给的好

代码也是能用, 不过就如ChatGPT-4说的, 最后的数组是随机的, 并不符合我的要求.

我自己也能写出来, 不过以前我可能会搜索一下Promise.all的用法和例子, 然后写一下测试一下, 通过ChatGPT我很方便的得到了我要的, 大部分情况下就能直接用, 省去了思考的过程, 最多就是代码调整一下改改BUG. 通过了ChatGPT大大提高了工作生产效率, 在这个例子中, 能节省我几分钟的时间.

我相信微软的Github Copilot也能达到类似惊人的效果.

ChatGPT为什么每次给出的结果不完全一样?

你可能会好奇: 为什么有的时候ChatGPT给出的答案是不一样的.

即使是同一问法, 重新生成答案也不太可能完全一样, 因为ChatGPT是一个字一个字生成答案, 每次生成一个词就会预测下一个词的概率, 然后再组成新的Context来预测下面的词, 每个词的概率都是不一样的, 有一定的随机性.

英文: ChatGPT Refactors/Rewrites the Code using Promise.All – Sending Requests in Parallel

ChatGPT 可以拿来做什么?

ChatGPT 通用人工智能

强烈推荐

微信公众号: 小赖子的英国生活和资讯 JustYYUK

阅读 桌面完整版
Exit mobile version