javascript - 在异步回调中使用 _.after() ,污染数组变量

标签 javascript node.js underscore.js lodash

我希望这个问题不是重复的,我在这里搜索了类似的问题,但没有得到匹配的结果。

node.js中,下面的代码污染了storage变量。我真的不明白为什么。

var _ = require('underscore'); // same result by using lodash

function add(arr, callback) {
    var l = arr.length,
        storage = [];

    function doCallback() {
        callback(storage);
    }

    returnStorage = _.after(l, doCallback);
    _.each(arr, function (a) {
        _.delay(function () {
            storage.push(a);
            returnStorage();
        }, 10);
    });
}

function callbackHandler(result) {
    console.log(result);
}

add([1,2,3], callbackHandler),
add([4,5,6,7], callbackHandler);

// in console will print wrong result:
// [ 4 ]
// [ 4, 5 ]
// [ 4, 5, 6 ]
// [ 4, 5, 6, 7 ]

但是,如果我不使用 _.after() 它将给出预期的结果。使用下划线lodash给出相同的结果。

下面的代码工作正常。

var _ = require('underscore'); // same result by using lodash

function add(arr, callback) {
    var l = arr.length,
        storage = [];

    function returnStorage() {
        if (storage.length == l) {
            callback(storage);
        }
    }

    _.each(arr, function (a) {
        _.delay(function () {
            storage.push(a);
            returnStorage();
        }, 10);
    });
}

function callbackHandler(result) {
    console.log(result);
}

add([1,2,3], callbackHandler),
add([4,5,6,7], callbackHandler);

// in console will print correct result:
// [ 1, 2, 3 ]
// [ 4, 5, 6, 7 ]

我应该如何确定根本原因!

最佳答案

JavaScript 上下文的魔力。当你做的时候:

returnStorage = _.after(l, doCallback);

returnStorage 与第二次调用 add 相同。

您需要使用 var 声明它,以使其成为函数的新内容和本地内容。

var _ = require('underscore'); // same result by using lodash

function add(arr, callback) {
    var l = arr.length,
        storage = [];

    function doCallback() {
        callback(storage);
    }

    var returnStorage = _.after(l, doCallback);
    _.each(arr, function (a) {
        _.delay(function () {
            storage.push(a);
            returnStorage();
        }, 10);
    });
}

function callbackHandler(result) {
    console.log(result);
}

add([1,2,3], callbackHandler),
add([4,5,6,7], callbackHandler);

// in console:
// [ 1, 2, 3 ]
// [ 4, 5, 6, 7 ]

一些解释:

第一次调用 add() 时,returnStorage未定义。然后它将被定义为全局上下文,因为它们之前没有 var

在第二次调用时,会声明该变量,并且在设置它时,也会为第一次 add() 调用设置它。因此,10 毫秒后,[1,2,3] 的每个元素都调用了 returnStorage(第二个),[4,5,6] 的下一个元素也已调用,7] 将触发 returnStorage 回调,任何进一步的调用也会触发它。

关于javascript - 在异步回调中使用 _.after() ,污染数组变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34332391/

相关文章:

javascript - 如何为选择框中的选项添加背景图片?

javascript - 在处理一些基本的添加时,令人难以置信的 javascript 失败!

node.js - 更改更新不起作用 Angular-CLI (ng-serve)

javascript - 是否可以在 Underscore.js 中获取要排序的索引?

javascript - 引用错误 : variable is not defined with underscore template

javascript - 如何从 Controller 的 "<select></select>" View 中获取 "ActionResult"的值?

javascript - 浏览器状态 - Javascript/JQuery

javascript - 下划线/Lodash : Group object by substring of key

javascript - 从中间件通过 req.body 传递变量

javascript - 如何使用 Bluebird 处理被拒绝的 promise 中的资源?