2017-09-16 58 views
0

我正在編寫一個模塊,它具有使用Promise.all()來發送電子郵件給幾個用戶的承諾的功能。剝離下來的代碼,我能夠重現問題下面的代碼片段:Promise.all()解析爲每個承諾提供相同的值

var getPromise = function(data) { 
    return new Promise((resolve, reject) => { 
     console.log("After Calling:\t\t", data.user); 
     setTimeout(function() { 
       console.log("While Resolving:\t", data.user); 
       return resolve(data); 
      }, 
      Math.random() * 1000); 
    }); 
} 

var getAllPromises = function(users, options) { 
    var promises = []; 
    users.forEach(user => { 
     var userSpecificOptions = options; 
     // var userSpecificOptions = {}; 
     userSpecificOptions.user = user; 
     promises.push(getPromise(userSpecificOptions)); 
    }); 
    return Promise.all(promises); 
} 

var userlist = ["help", "promises", "are", "tough"]; 
var commonoptions = { 
    str: "something", 
} 

getAllPromises(userlist, commonoptions) 
    .then(data => console.log("Data:\n", data)) 

這給了我下面的輸出:

After Calling:  help 
After Calling:  promises 
After Calling:  are 
After Calling:  tough 
While Resolving:  tough 
While Resolving:  tough 
While Resolving:  tough 
While Resolving:  tough 
Data: 
[ { str: 'something', user: 'tough' }, 
    { str: 'something', user: 'tough' }, 
    { str: 'something', user: 'tough' }, 
    { str: 'something', user: 'tough' } ] 

然而,切換聲明userSpecificOptions

 // var userSpecificOptions = options; 
     var userSpecificOptions = {}; 

得到正確結果:

After Calling:  help 
After Calling:  promises 
After Calling:  are 
After Calling:  tough 
While Resolving:  help 
While Resolving:  promises 
While Resolving:  are 
While Resolving:  tough 
Data: 
[ { user: 'help' }, 
    { user: 'promises' }, 
    { user: 'are' }, 
    { user: 'tough' } ] 

可能是什麼問題?我覺得可能有些事情我對Promises的工作方式缺乏瞭解。

回答

1

你讓所有userSpecificOptions情況下指的是同一options對象:

var userSpecificOptions = options; 

所以,當你分配給userSpecificOptions.user,你居然修改options

相反,你應該採取的options副本:

var userSpecificOptions = Object.assign({}, options); 

那麼任何變動,特別userSpecificOptions對象,不會影響options或任何其他變量。

0

此問題不在承諾中。在JavaScript對象是通過引用傳遞。這意味着在這種情況下,你總是改變同一個對象,最後的改變發生,你會看到所有相同的結果。當創建新對象而不是修改存在對象時,它正常工作。