它看起來像的總體目標是:
- 對於
urls
每個條目,請撥打$.get
並等待它完成。
- 如果返回只是沒有「未來」的響應,保持一個響應
- 如果返回了「下一個」,我們要請「下一個」,以及再保持二者的響應。
- 當所有工作完成時用
response
調用回調。
我會改變#2,所以你只需返回承諾並用response
來解決。
有關承諾的一個重要的事情是,then
返回新承諾,這將既可以與你then
返回的內容(直接,如果你返回一個非thenable值,或間接,如果你返回thenable解決,通過奴役自己到那可以)。這意味着如果您有承諾來源(在這種情況下爲$.get
),則幾乎不需要使用new Promise
;只需使用您使用then
創建的承諾。 (。而catch
)
看評論:
function testCase(urls) {
// Return a promise that will be settled when the various `$.get` calls are
// done.
return Promise.all(urls.map(function(url) {
// Return a promise for this `$.get`.
return $.get(url)
.then(function(response) {
if (response.meta && response.meta.next) {
// This `$.get` has a "next", so return a promise waiting
// for the "next" which we ultimately resolve (via `return`)
// with an array with both the original response and the
// "next". Note that since we're returning a thenable, the
// promise created by `then` will slave itself to the
// thenable we return.
return $.get(url + "&offset=" + response.meta.next)
.then(function(nextResponse) {
return [response, nextResponse];
});
} else {
// This `$.get` didn't have a "next", so resolve this promise
// directly (via `return`) with an array (to be consistent
// with the above) with just the one response in it. Since
// what we're returning isn't thenable, the promise `then`
// returns is resolved with it.
return [response];
}
});
})).then(function(responses) {
// `responses` is now an array of arrays, where some of those will be one
// entry long, and others will be two (original response and next).
// Flatten it, and return it, which will settle he overall promise with
// the flattened array.
var flat = [];
responses.forEach(function(responseArray) {
// Push all promises from `responseArray` into `flat`.
flat.push.apply(flat, responseArray);
});
return flat;
});
}
注意如何我們從不使用catch
那裏。我們將錯誤處理推遲給調用者。
用法:
testCase(["url1", "url2", "etc."])
.then(function(responses) {
// Use `responses` here
})
.catch(function(error) {
// Handle error here
});
的testCase
函數看起來很長,但是這是評論,只是因爲。這裏是沒有它們的:
function testCase(urls) {
return Promise.all(urls.map(function(url) {
return $.get(url)
.then(function(response) {
if (response.meta && response.meta.next) {
return $.get(url + "&offset=" + response.meta.next)
.then(function(nextResponse) {
return [response, nextResponse];
});
} else {
return [response];
}
});
})).then(function(responses) {
var flat = [];
responses.forEach(function(responseArray) {
flat.push.apply(flat, responseArray);
});
return flat;
});
}
......如果我們使用ES2015的箭頭函數,它會更加簡潔。 :-)
在評論你問:
難道這處理,如果有下一個未來?就像第3頁的結果?
我們可以做到這一點通過封裝該邏輯到一個功能,我們使用,而不是$.get
,我們可以遞歸使用:
function getToEnd(url, target, offset) {
// If we don't have a target array to fill in yet, create it
if (!target) {
target = [];
}
return $.get(url + (offset ? "&offset=" + offset : ""))
.then(function(response) {
target.push(response);
if (response.meta && response.meta.next) {
// Keep going, recursively
return getToEnd(url, target, response.meta.next);
} else {
// Done, return the target
return target;
}
});
}
然後我們的主要testCase
簡單:
function testCase(urls) {
return Promise.all(urls.map(function(url) {
return getToEnd(url);
})).then(function(responses) {
var flat = [];
responses.forEach(function(responseArray) {
flat.push.apply(flat, responseArray);
});
return flat;
});
}
你在哪裏初始化'promises'?我看到你推動它,但我沒看到你創造它。 –
什麼是'url'? (如果它是一個數組,通常是一個複數,例如'urls'。) –
爲什麼'response.resource = response.resource.concat(v.resource);'?每次創建一個全新的陣列...? –