2014-09-01 56 views
2

之間的區別我雖然這代碼將工作:Q諾。 。當和。然後

var promise = function(val) { 

    var _val = val; 

    return setTimeout(function(_val) { 

     var newVal = val/10; 

     return { 
      newVal : newVal, 
      message : 'it just to be a ' + val 
     }; 
    }, 3000); 
}; 

Q.when(promise(400)).then(function(obj) { 
    return console.log('jaaaaj !', obj); 
}, function() { 
    return console.log('no yet...'); 
}); 

JSFiddle

我的想法是一樣:四秒後,當setTimeout的完成自己的工作,Q庫將趕上第一個回調回報並顯示具有兩個屬性的對象:newVal : 4message : 'it just to be a ' + 400。相反,我有奇怪的1號作爲OBJ成功回調...

BTW有什麼區別.when.then Q庫?

+0

你實際上不能從'setTimeout'返回任何東西,因爲它是異步的。此外,從上下文(以及來自公認的參數)應該清楚的是,「什麼時候」包裝了一個承諾,以便它可以與「then」鏈接,從而觸發回調 - 當承諾得到解決時。 – Mathletics 2014-09-01 23:04:00

回答

8

.when()將一個或多個承諾作爲參數。您正在向它傳遞一個計時器句柄,因此它將立即執行.then()處理程序。

.when()當你傳遞給它的東西完成時,沒有魔法辨別能力。您必須傳遞一個或多個承諾,並監控這些承諾何時解決。

此外,您不能從setTimeout()返回任何內容,但如果您在setTimeout()內解決了承諾,則可以將數據傳遞給.resolve()方法。

你可以做這樣的事情:

var promise = function(val) { 
    var defer = Q.defer(); 

    setTimeout(function() { 

     var newVal = val/10; 

     defer.resolve({ 
      newVal : newVal, 
      message : 'it just to be a ' + val 
     }); 
    }, 3000); 

    // return the promise 
    return defer.promise; 
}; 

Q.when(promise(400)).then(function(obj) { 
    return console.log('jaaaaj !', obj); 
}, function() { 
    return console.log('rejected...'); 
}); 

但是,當你只有一個承諾,你甚至不需要Q.when()。你可以這樣做:

promise(400).then(function(obj) { 
    return console.log('jaaaaj !', obj); 
}, function() { 
    return console.log('rejected...'); 
}); 
+0

「你不能從setTimeout()返回任何東西」 - 是正確的,但類似地,你不能將任何東西*傳遞給* setTimeout。在setTimeout函數中使用的任何對象/值必須是「自生成的」(例如,var foo = 99;)或從寫入函數(但不一定是setTimeout本身)的詞法環境中獲取。因此''setTimeout(function(_val){'可以被重寫爲'setTimeout(function(){',並且'var _val = val;'行可以被刪除,因爲'val'可以從setTimeout函數內部自動到達(as顯示爲'var newVal = val/10;') – 2014-09-02 01:47:55

+0

哦,是的,第三種方法是使用[Function.prototype.bind()](https:// developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind),它返回一個帶有「預先通過」參數(和上下文)的新函數。 – 2014-09-02 02:06:47

+0

@ Roamer-1888 - 你'沒有直接將參數傳遞給'setTimeout()'回調函數是正確的,我沒有看到原本在OP代碼中的內容,但是幸運的是,他們沒有使用他們聲明的參數,無論如何,我在我的回答中已經將它從代碼中移除了,在這種情況下,不需要傳遞任何東西,因爲它可以直接訪問父範圍以獲得'val'。是的,可以使用'.bind()',儘管在這個例子中不需要。 – jfriend00 2014-09-02 05:01:30