2016-04-10 9 views
5
は、本雄弁のJavascriptの第17章で exercises

一つはPromise.all()メソッドを実装することで、私は(動作しない)この実装を思い付いた:実装Promise.all

function all(promises) { 
    return new Promise(function(success, fail) { 
    var successArr = new Array(promises.length); 
    if (promises.length == 0) 
     success(successArr); 
    var pending = promises.length; 
    for (var i = 0; i < promises.length; i++) { 
     promises[i].then(function(result) { 
     successArr[i] = result; 
     pending -= 1; 
     if (pending == 0) 
      success(successArr); 
     }, function(error) { 
     fail(error); 
     }); 
    } 
    }); 
} 


// Testing 
function soon(val) { 
    return new Promise(function(success) { 
    setTimeout(function() { success(val); }, 
       Math.random() * 500); 
    }); 
} 
all([soon(1), soon(2), soon(3)]).then(function(array) { 
    console.log("This should be [1, 2, 3]:", array); 
}); 
// => [undefined, undefined, undefined, 3] 

興味深いことに、著者のソリューションは、私の場合には、forループの代わりに、約束の配列を反復処理するためにはforEachの使用から離れ似ています。

function all(promises) { 
    return new Promise(function(success, fail) { 
    var successArr = new Array(promises.length); 
    if (promises.length == 0) 
     success(successArr); 
    var pending = promises.length; 
    promises.forEach(function(promise, i) { 
     promise.then(function(result) { 
     successArr[i] = result; 
     pending -= 1; 
     if (pending == 0) 
      success(successArr); 
     }, function(error) { 
     fail(error); 
     }); 
    }); 
    }); 
} 

// Testing 
function soon(val) { 
    return new Promise(function(success) { 
    setTimeout(function() { success(val); }, 
       Math.random() * 500); 
    }); 
} 
all([soon(1), soon(2), soon(3)]).then(function(array) { 
    console.log("This should be [1, 2, 3]:", array); 
}); 
// => [1, 2, 3] 

はなぜ使用しますforeachはここにすべての違いになりません?私は」それは、ある人が作成したスコープに関連するものだと思いますonymous関数がforEachに渡されましたが、その仕組みがわかりません。

+0

@Bergiこの質問は重複していません。少なくとも、オリジナルの質問は重複しているとマークしていません。 –

+0

@AlexMills:どのようにそうですか?この問題は、非同期コールバックの 'i'変数の値です。これは正規なdupeターゲットで記述されているものとまったく同じです。 OPの自己回答でも同じことができます。あなたは何と答えていますか? – Bergi

答えて

6

変数はiです。私たちはforループを使用しているため、約束が解決する前に変更されますが、forEachバージョンでは、i変数のスコープが正しく設定されているため、自分のi変数

+0

ありがとうございます!よく目撃された。これはクロージャーと呼ばれています - 私はあなたの本がそれを説明するとは思わないが、あなたはそれらをよく知るようになるでしょう。説明については、[この質問](http://stackoverflow.com/questions/111102/how-do-javascript-closures-work)を参照してください。 – Rhumborl

+0

リンクありがとうございます;) – Edmeral