How do I do this jquery pattern in dart? [duplicat

2019-09-06 01:10发布

问题:

This question already has an answer here:

  • Waiting for Futures raised by other Futures 1 answer

I'm trying to convert the following javascript/jquery code into dart, but I'm having problems understanding how futures work.

function fnA() {
    fnB().then(function() {
        // do something
    }
}

function fnB() {
   var ret = $.Deferred();

   _db.open(database_name).then(function() {
       var defers = [];

       _db.keys().forEach(function(key_name) {
          var key_dfd = $.Deferred();
          defers.push(key_dfd);
          _db.getByKey(key_name).then(function(data) {
              key_dfd.resolve(data);
          });
       });
       $.when(defers).then(ret.resolve);
   })
   .fail(function() {
       ret.reject();
   });

   return ret.promise();
}

I thought I could do it similar to following, but it doesn't seem to work:

(I'm using lawndart for the database)

void fnA() {
    fnB().then((_) {
        // Here, all keys should have been loaded
    });
}

Future fnB() {
    return _db.open().then((_) {
        return _db.keys().forEach((String key_name) {
             return _db.getByKey(key_name).then((String data) {
                  // do something with data
                  return data;
             });
        });
    });
}

回答1:

I made some improvments but haven't tested the code:

void fnA() {
    fnB().then((_) {
        // Here, all keys should have been loaded
    });
}

Future fnB() {
  return _db.open().then((_) {
    List<Future> futures = [];
    return _db.keys().forEach((String key_name) { 
      futures.add(_db.getByKey(key_name).then((String data) {
        // do something with data
        return data;
      }));
    }).then(() => Future.wait(futures));
  });
}


回答2:

Sticking with JavaScript/jQuery for a moment, fnB can (assuming compatibility of Promise implementations) be written more efficiently as follows :

function fnB() {
    return _db.open(database_name).then(function() {
        return $.when.apply(null, _db.keys().map(function(key_name) {
            return _db.getByKey(key_name);
        }));
    });
}

As far as I can tell from the Dart documentation, this should translate into Dart something like this :

function fnB() {
    return _db.open().then(function() {
        return Future.wait(_db.keys().map(function(key_name) {
            return _db.getByKey(key_name);
        }));
    });
}

The assumption about Promise compatibility disappears on translation, but the above code assumes that _db.keys() returns an Array. If this assumption is not valid, then the code will be slightly different.

fnA will be something like this :

function fnA() {
    fnB()
        .then((List values) => doSomething(values))
        .catchError((e) => handleError(e));
}

That's the essence of it. You may need to work at the detail.