1

我有以下具有以下结构的代码:

doSomething '/', ->
  waitForthis '#e', ->
    waitForSomethingElse '#el', ->
      #actually do it

如果我想使用延迟/承诺是这样的:

doSomething().then(waitForthis).then(waitForSomethingElse);

我将在哪里创建延迟,然后每个人都会返回一个承诺?

我只是在寻找一些粗略的建议来帮助我入门。

我可能会为此使用 jquery deferreds。

4

3 回答 3

0

If you're looking for something like:

Send request A
when A returns,
Send request B(result a)
when B returns,
Do C(response b)

Then you need to make each one a promise, and you need to pay attention to closures (because you can't collect the return value from a callback).

a_done = something_that_returns_a_promise();
a_done.then(function (a_result) {
    var b_done = something_that_returns_a_promise(a_result);
    b_done.then(function (b_result) { do_C(b_result); });
});

If you're looking for something like

Send request A
Send request B

when A && B return,
Do C

Then you're looking at a function which will take a number of promises, and return a promise.

a = something_returning_a_promise();
b = something_returning_a_promise();
a_and_b_done = when(a, b);

a_and_b_done.then(function (result1, result2) { do_c(result1, result2); })
            .then(show_results);

Doing something like

a_done.then(fillRows).then(showResults);

Doesn't let you make multiple async calls... ...what it does is allows you to chain a bunch of synchronous tasks one after the other (or make async calls where the order they arrive in doesn't matter at all).

.then

or

.done

or whatever, doesn't do anything special -- it adds a task to an array.
When the async promise returns (or if it's already returned and has been resolved), it just goes through that list in order, and fires all of the callbacks, passing whatever data it was resolved with (and calling the "success" or "failure" callbacks, based on the success of the operation).

So you need one promise for each async callback, and if you're trying to chain callbacks together, you still need to wrap each one inside of a closure (the closure which will pass the result to whatever is constructing your next promise).

I'm using the jQuery $.Deferred(), deferred.promise(), deferred.resolve(), deferred.reject(), promise.done(), promise.fail() and $.when() here:
other libraries might have different terminology, but will behave similarly.

var ImageLoader = function (name, format) {
    var loading = $.Deferred(),

        img = new Image(),
        url = name + (format || ".png");

    img.onload = function () {
        loading.resolve(img);
    };

    img.onerror = function () {
        loading.reject("Image failed to load:" + name);
    };

    img.src = url;

    return loading.promise();
};


var imgLoaded = ImageLoader("//mysite.com/myimg");

imgLoaded.done(function () { console.log("img 1 loaded"); });
imgLoaded.fail(function (msg) { console.log(msg); });

var img2Loaded = ImageLoader("//yoursite.com/yourimg", ".jpg");
img2Loaded.done(function () { console.log("img 2 loaded"); });
img2Loaded.fail(function (msg) { console.log(msg); });


var showImages = function (img1, img2) {
    document.body.appendChild(img1);
    document.body.appendChild(img2);
};

var both_loaded = $.when(imgLoaded, img2Loaded);
both_loaded.done(showImages);

This is a messy and convoluted example, but rather than making it elegant, I figured I'd try to write it in a way that shows all of the pieces.

于 2012-12-11T00:17:44.377 回答
0

(假设 jQuery)

为了确保链接,每个步骤都需要返回一个承诺。

那就是 then() 所做的,所以这里没有问题。

doSomething() 也需要返回一个承诺。你可以通过让 doSomething() 创建一个 deferred 并返回它的 Promise 来做到这一点。

一些 jQuery 函数已经包含了一个 deferred,你可以直接用 then() 链接它们。例如:

$.ajax(...).then(...)

查看本文以获取更多详细信息和实时示例。

于 2012-12-10T23:28:12.703 回答
0

像这样的东西:

doSomething().then(waitForthis).then(waitForSomethingElse);

它宁愿是

doSomething('/').then( function() {
    return waitForthis('#e');
}).then( function() {
    return waitForSomethingElse('#el');
});

或者你使用.bind().

我将在哪里创建延迟,然后每个人都会返回一个承诺?

是的,每个函数都会返回一个承诺。在 jQuery 中,“Deferred”是延迟对象的构造函数,调用“promise()”返回的对象只有 addCallback 函数,不暴露触发方法。只需检查文档及其许多示例。

于 2012-12-11T01:05:40.650 回答