Write a promise [duplicate]

2019-09-03 07:46发布

问题:

This question already has an answer here:

  • How do I convert an existing callback API to promises? 20 answers

I have a widget <input type='file' style='display:none' id='foo' /> and some code that opens the dialog like this

$("#foo").click();

Now I need to set up some code so it runs after the user makes a selection and closes the dialog.

I understand that this is promise pattern but I'm not sure how to go about writing a promise. Could someone give me some guidance? It's no problem to put a change handler on the input widget but I need to code up something like this:

$("#foo").click().then(function(){
  $("#theForm").submit();
});

As I understand promises the case where the postcondition is met (user selects a file and clicks OK) is called resolved and there's another name that just now eludes me for the case where the postcondition isn't met.

Those of you who are about to suggest that I do this

$("#foo").change(function(){
  $("#theForm").submit();
}

I am aware of this solution but it doesn't teach me anything about writing promises.

回答1:

There's ample documentation on promises out in the world, but here's the skinny:

var promise = new Promise(function(resolve, reject) {
  // do a thing, possibly async, then…

  if (/* everything turned out fine */) {
    resolve("Stuff worked!");
  }
  else {
    reject(Error("It broke"));
  }
});

and then:

promise.then(function(result) {
  console.log(result); // "Stuff worked!"
}, function(err) {
  console.log(err); // Error: "It broke"
});

http://www.html5rocks.com/en/tutorials/es6/promises/ that might help! good luck



回答2:

You need to use a Promise constructor, which will give you the ability to resolve the promise:

var p = new MyLib.Promise(function(resolver) {
    $("#foo").one("click", resolver);
}); // a promise that resolves with the next click on #foo
p.then($.fn.submit.bind($("#theForm"))); // or whatever

With jQuery, you'd need to use the Deferred pattern:

$.fn.nextEvent = function(type) {
    var d = new $.Deferred();
    this.one(type, function() {
        d.resolveWith(this, arguments);
    });
    return d.promise();
};

$("#foo").nextEvent("click").then(function(e) {
    $("#theForm").submit();
});