【问题标题】:Recursive async delayed promise overlapping递归异步延迟承诺重叠
【发布时间】:2018-11-03 20:55:25
【问题描述】:

用例如下:我想每 X 毫秒查询一次 URL,直到得到肯定的答复。

我正在尝试在 JS(节点)中实现这一点,并且遇到了多个此类请求的问题。 如果我只启动其中一个“链式调用”,一切正常。

但如果我尝试并行运行其中的一些,“最后一个获胜”(第一个永远不会解决)。我似乎在使用对同一对象或其他东西的引用,但我无法弄清楚。

注意“masterCounter”和“id”变量是如何被覆盖的,尽管它们是按值作为参数传递的。

这是工作代码(“第二”胜过“第一”):

(安装请求包https://www.npmjs.com/package/request可以使用node运行)

var req = require('request');

const ASK_EVERY_MS = 500;
const AT_MOST_MS = 5000;

var childRecursive = (t, resolve, reject, t0, id, masterCounter) => {    
    var duration = process.hrtime(t0);    
    duration = (duration[0] * Math.pow(10, 9) + duration[1]) / Math.pow(10, 6)
    if (duration + t > AT_MOST_MS) {
        reject('timeout');
    } else {
        var options = {
            url: 'http://www.google.com',
            json: false,
            headers: {
                timeout: 1000
            }
        };
        callback = function (error, response, body) {
            if (!error) {
                console.log('body', body.substring(0, 100));
                if (masterCounter % 5 == 0) {
                    return resolve("success!!!");
                } else {
                    return childRecursive(ASK_EVERY_MS, resolve, reject, t0, id, masterCounter + 1, req);
                }
            } else {
                console.log('problem with submission GET request: ' + error);
                return reject(error);
            }
        }
        console.log(id + ' masterCounter is ' + masterCounter);
        setTimeout(() => {
            console.log(id + ' requesting...');
            req.get(options, callback);
        }, t);
    }
};

var t0 = process.hrtime();
var first = new Promise((resolve, reject) => childRecursive(0, resolve, reject, t0, 'FIRST', 101));
first.then(() => {
    console.log('FIRST done');
});
var scnd = new Promise((resolve, reject) => childRecursive(0, resolve, reject, t0, 'SECOND', 201));
scnd.then(() => {
   console.log('SECOND done');
});

和输出:

FIRST masterCounter is 101
SECOND masterCounter is 201
FIRST requesting...
SECOND requesting...
body <!doctype html><html itemscope="" itemtype="http://schema.org/WebPage" lang="hr"><head><meta content
SECOND masterCounter is 202
body <!doctype html><html itemscope="" itemtype="http://schema.org/WebPage" lang="hr"><head><meta content
SECOND masterCounter is 202
SECOND requesting...
SECOND requesting...
body <!doctype html><html itemscope="" itemtype="http://schema.org/WebPage" lang="hr"><head><meta content
SECOND masterCounter is 203
body <!doctype html><html itemscope="" itemtype="http://schema.org/WebPage" lang="hr"><head><meta content
SECOND masterCounter is 203
SECOND requesting...
SECOND requesting...
body <!doctype html><html itemscope="" itemtype="http://schema.org/WebPage" lang="hr"><head><meta content
SECOND masterCounter is 204
body <!doctype html><html itemscope="" itemtype="http://schema.org/WebPage" lang="hr"><head><meta content
SECOND masterCounter is 204
SECOND requesting...
SECOND requesting...
body <!doctype html><html itemscope="" itemtype="http://schema.org/WebPage" lang="hr"><head><meta content
SECOND masterCounter is 205
body <!doctype html><html itemscope="" itemtype="http://schema.org/WebPage" lang="hr"><head><meta content
SECOND masterCounter is 205
SECOND requesting...
SECOND requesting...
body <!doctype html><html itemscope="" itemtype="http://schema.org/WebPage" lang="hr"><head><meta content
SECOND done
body <!doctype html><html itemscope="" itemtype="http://schema.org/WebPage" lang="hr"><head><meta content

【问题讨论】:

    标签: javascript recursion scope promise closures


    【解决方案1】:

    您的问题是 implicitly global callback 变量。应该是

    var callback = function (error, response, body) { /*
    ^^^ */
    

    function callback(error, response, body) {
    

    请始终use strict mode 以避免此类错误!

    【讨论】:

      猜你喜欢
      • 2012-12-17
      • 2016-09-03
      • 1970-01-01
      • 1970-01-01
      • 2015-12-08
      • 2019-03-10
      • 2015-03-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多