承諾是一個單向鎖存器。一旦以價值解決或以理由拒絕,其狀態和價值/理由永遠不會改變。所以,不管你做了多少次.then()
這個承諾,你總是會得到相同的結果。這就是「不變」的意思。
我不確定你的意思是保證值。不能保證承諾永遠解決。它可能會拒絕(因此沒有價值),或者如果操作沒有完成,它可能永遠不會解決或拒絕。
操作承諾類型的一個示例是爲異步操作(如Ajax調用或從文件中讀取某些字節)而設計的。操作是異步的(操作開始後解釋器的正常執行繼續),操作具有特定的開始和結束。在大多數情況下,操作可能會成功完成,在這種情況下,操作可能會有值,或者可能會以錯誤結束,在這種情況下會有錯誤。值和錯誤都可以是對象,所以如果結果不僅僅是一個簡單的值,它們可以有很多屬性。
一個Ajax調用,例如有一個特定的開始和結束。它不能一次結束,因此它是承諾的完美搭配。你得到了一個表示ajax操作最終結果的承諾。然後註冊滿足處理程序和拒絕處理程序,並在操作完成時調用其中一個或另一個。
普通回調函數只是回調函數,每次調用它們時可以賦予不同的值,並且可以多次調用它們。
如果您希望在某個操作完成且操作具有特定開始和結束時只收到一次通知,請使用承諾。
如果您想多次收到通知,請使用普通回調或事件偵聽器或觀察者或其他可以多次觸發的機制。
作爲一個簡單的例子,setTimeout()
非常適合承諾。
function delay(t) {
return new Promise((resolve, reject) => {
resolve();
}, t);
}
// delay 100ms before starting the operation
delay(100).then(run);
或者使用藍鳥無極庫循環的URL列表一點更多地參與操作,下載內容,分析的內容,看在內容對於一些特定的URL,然後將它們收集齊全(否則被稱爲刮):
const Promise = require('bluebird');
const request = Promise.promisifyAll(require('request'), {multiArgs: true});
const cheerio = require('cheerio');
function getAsync() {
return request.getAsync.apply(request, arguments).then(argArray => {
// return only the response html
if (argArray[0].statusCode !== 200) {
throw new Error("response statusCode = " + argArray[0].statusCode);
}
return argArray[1];
});
}
const urls = [....];
Promise.mapSeries(urls, url => {
return getAsync({url: url, gzip: true}).then(html => {
let $ = cheerio.load(html);
let resources = $("#external_resources_list li a.filename");
resources.each(index, link) => {
let href = $(link).attr("href");
console.log(href);
results.push(href);
});
}).catch(err => {
// log error, but keep going
console.log(url, err);
});
}).then(() => {
// got all results here
console.log(results);
});
而且,setInterval()
根本不會有承諾,因爲它要反覆每次通知的時間間隔通行證,這將根本無法與承諾攜手。堅持回撥setInterval()
。
一個承諾是一個單向鎖。一個是用一個價值來解決或者被一個理由拒絕的,它的狀態和價值/理性永遠不會改變。所以,無論你做了多少次「.then()」,都會得到相同的結果。普通的回調只是回調函數,每次調用時都可以賦予不同的值。如果您希望在某個操作完成時只收到一次通知,請使用承諾。如果您想多次收到通知,請使用普通回調或偵聽器或觀察者或其他可以觸發多次的其他機制。 – jfriend00