首页 > 解决方案 > 如何跟踪单个 JavaScript 进程?

问题描述

标题可能具有误导性,因为我不确定如何用一句话来总结我的问题。

我有一个场景,我的脚本必须将数据并行发布到多个 URL,我正在努力弄清楚如何直观地跟踪每个单独的 URL 发生的情况(即发布的内容和返回的内容)。这是我的代码:

const axios = require('axios');

const postData = async (order_id) => {
    for(let i = 0; i < 10; i++){
        let data = await grabDataFromSomewhere(...);
        await axios.post(`http://example.net/orders/${order_id}`, {data})
            .then(response => {
                //console.log(response.data);
                console.log(i, `POSTING TO http://example.net/orders/${order_id}`);
                console.log("--- Response:", response.data)
            })
    }
}

const orders = ['5f96499a3a19135ad163', '99a3a19135ad1630238', '6499a3a19135ad16302']

orders.forEach(id => {
    postData(id)
})

该脚本在将正确的数据发布到正确的 URL 方面运行良好,但控制台输出显然是一大混乱,因为所有 axios 请求都完成并将其输出转储到同一个控制台。

postData在自己的专用控制台中关注每个单独调用函数的输出的最佳方法是什么?

对于那些在 Linux 上使用screen的人来说,可视化我正在寻找的内容的一个好方法是想象每次调用都会生成postData一个新屏幕,我可以随时附加它并查看函数的输出。

标签: javascriptnode.js

解决方案


我建议使用以下代码。这个想法是并行发出所有请求,但按照它们发出的顺序记录它们。如果您运行以下代码并检查控制台,您将看到响应以随机间隔发生,但它们始终以正确的顺序记录在浏览器中。诀窍是创建一个表示 post 请求的 Promise 映射,然后以这样的方式链接它们:当第一个请求返回时,它被记录,然后当第二个请求返回时,它被记录,依此类推。如果一个请求无序返回,它的 promise 仍然会被解决,但我们只会在它的所有前辈都到达后才记录它。

我意识到这并不是您所要求的,但这就是我试图解决您面临的问题的方式。

此外,您有一个多维数组,因此在将其内容映射到 Ajax 请求之前,我会将其展平为一维数组。

此解决方案基于 Jake Archibald 的文章https://web.dev/promises/

const orders = ['alpha', 'beta', 'gamma', 'delta', 'epsilon']

function postToAxios(data) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      console.log('in set timeout', data);

      if (data === 'beta') {
        reject('rejected: ' + data);
      } else {
        resolve('resolved: ' + data);
      }
    }, Math.random() * 1000);
  });
}

function createLogEntry(data) {
  const el = document.createElement('div');
  el.className = "log-entry";
  el.textContent = data;
  return el;
}

function createErrorEntry(data) {
  const el = document.createElement('div');
  el.className = "error-entry";
  el.textContent = data;
  return el;
}

orders.map(postToAxios)
  .reduce(function(sequence, promise) {
    return sequence
      .then(function() {
        return promise;
      }).then(function(result) {
        log.append(createLogEntry(result))
      }, function(reason) {
        log.append(createErrorEntry(reason));
      });
  }, Promise.resolve()).then(() => {
    console.log('all done');
  });
.log-entry,
.error-entry {
  margin: 5px;
  border: dotted 1px grey;
  padding: 10px;
}

.error-entry {
  color: red;
  border-color: currentcolor;
}
<div id="log"></div>


推荐阅读