繁体   English   中英

如何突破Jquery的每个循环

[英]How to Break out of Jquery's Each Loop WITH PROMISE

我的问题是除了: 如何突破每个循环的jQuery

我需要退出jquery $ .each()但在这种情况下我不能返回FALSE,因为退出条件是触发一个将解决延迟的函数。 所以我需要退出每一个,但有一个承诺。

function KillLayer(id) {
    var defer = $.Deferred();
    $.each(vm.get("DeviceData"), function (idx, item) {
        if (item.Type == id) {
            vm.DeviceData.splice(idx, 1); // remove the item from the list
            removeLayer(defer, id)  // delete it from the PouchDB (IDB) database (async)
            return defer.promise();
        }
    });
    defer.resolve(); // layer was not found, so just resolve & return
    return defer.promise();
}

试试这样。

objDP = null;  // To get Deferred’s Promise object.

$.each(vm.get("DeviceData"), function (idx, item) {
    if (item.Type == id) {
        vm.DeviceData.splice(idx, 1); // remove the item from the list
        removeLayer(defer, id)  // delete it from the PouchDB (IDB) database (async)
        objDP = defer.promise();
        return false;
    }
});

正如您所发现的那样,您无法在其each()循环内从KillLayer()返回,因为该上下文中的return语句具有不同的含义。

这里有几种不同的方法:

1:使用布尔标志来表示是否发生了删除,并相应地处理延迟。

function KillLayer(id) {
    var defer = $.Deferred(), deleted = false;
    $.each(vm.get("DeviceData"), function (idx, item) {
        if (item.Type == id) {
            vm.DeviceData.splice(idx, 1); // remove the item from the list
            removeLayer(defer, id);  // delete it from the PouchDB (IDB) database (async)
            deleted = true;
            return false;//break from each() loop
        }
    });
    return deleted ? defer.promise() : defer().resolve().promise();//return either a promise of deletion or a ready-resolved promise.
}

2 :(如果你可以控制removeLayer() )安排removeLayer()生成并返回自己的promise,而不是传递Deferred。 这将允许您简化KillLayer() ,如下所示:

function KillLayer(id) {
    var deletionPromise;
    $.each(vm.get("DeviceData"), function (idx, item) {
        if (item.Type == id) {
            vm.DeviceData.splice(idx, 1); // remove the item from the list
            deletionPromise = removeLayer(id);  // delete it from the PouchDB (IDB) database (async), and receive back a promise
            return false;//break from each() loop
        }
    });
    return deletionPromise || $.Deferred().resolve().promise(); //return either a promise of deletion from the DB, or a ready-resolved promise
}

虽然只有一个线差异,但我认为第二个appraoch更清洁。 由于removeLayer()执行异步活动,它应该真正返回自己的promise,而不是依赖于传递给它的Deferred。

这不会从每个循环中断,但它会使以下迭代不执行任何操作:

function KillLayer(id) {
    var defer = $.Deferred();
    var result = null;
    $.each(vm.get("DeviceData"), function (idx, item) {
        if (!result && item.Type == id) {
            vm.DeviceData.splice(idx, 1); // remove the item from the list
            removeLayer(defer, id)  // delete it from the PouchDB (IDB) database (async)
            result = defer.promise();
        }
    });
    return result || defer.resolve();
}

我想出了Beetroots独立回答#1。 首先,我意识到循环遍历$ each()并从javascript数组中删除您正在循环的项目是一种很好的错误方法。 我真的应该这样做:

$.each(clone(vm.get("DeviceData")), function (idx, item)` {

其中clone函数定义为:

function clone(obj) {
    return jQuery.extend({}, obj);
}

function deepClone(obj) {
    return jQuery.extend(true, {}, obj);
}

但在我的情况下,我不需要额外的保护,所以我刚刚更新了我的解决方案如下:

function KillLayer(id) {
    var defer = $.Deferred();
    var found = false;
    $.each(vm.get("DeviceData"), function (idx, item) {
        if (item.Type == id) {
            vm.DeviceData.splice(idx, 1);
            Compare();
            dbManifest.LayerInfo = vm.DeviceData.toJSON();
            removeLayer(defer, id)
            found = true;
            return false;
        }
    });
    if (!found) defer.resolve(); // layer was not found, so just resolve & return
    return defer.promise();
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM