2017-01-22 7 views
0

Promise().then()の理解のための例を作成したいと考えました。 私は、時間がかかり、同期的に完了しなければならない操作を持つ操作を作成しました。 コード以下である:Javascript Promise/Then例

// Example: long operation that takes time to execute 
var longOperation = function(id) { 

    var time = 1000 * Math.random(); 

    console.log('[' + id + '] Operation started for: ' + time + 'ms'); 

    setTimeout(function(err) { 
     console.log('[' + id + '] Completed operation: ' + time + 'ms'); 
     var count = id * 10; 
    }, 1000 * Math.random()); 

}; 

// Create new promise for longOperation 
var longOpPromise = function(id) { 

    return new Promise(function(resolve, reject) { 
     longOperation(id); 
     resolve(null); 
    }); 

}; 

// Create sequencing 
var runLongOperation = function(callback) { 

    var count1; 

    longOpPromise(1).then(function(count) { 

     count1 = count; 
     console.log('Count 1: ' + count1); 

     longOpPromise(2).then(function(count2) { 
      console.log('Count 2: ' + count2); 
      callback(null, count1, count2); 
     }); 

    }); 

}; 

// Run 
runLongOperation(function(err, count1, count2) { 
    if (err) console.error(err); 
    console.log('Count 1 ' + count1 + ' | Count 2: ' + count2); 
}); 

実行結果:

**** Output **** 
    [1] Operation started for: 626.77225866355ms 
    [1] Completed operation: 626.77225866355ms 

then()のメソッドを実行、またコールバックされていません。カウントが解決されていない可能性があります。

私はresolve(null)に変更した場合、これらは順番に実行していないが、:あなたの助けのための

**** Output **** 
    [1] Operation started for: 435.5367429088801ms 
    Count 1: null // This should come after [1] is completed 
    [2] Operation started for: 256.17250707000494ms 
    Count 2: null // This should come after [2] is completed 
    Count 1 null | Count 2: null // This should come after [2] is completed 
    [2] Completed operation: 256.17250707000494ms 
    [1] Completed operation: 435.5367429088801ms 

感謝を。

答えて

2

あなたは非同期処理が完了しあるときresolveを呼び出す必要があります。

longOperation(id); 
resolve(null); 

あなたは非同期操作を開始し、その後すぐ約束を解決されています。このコードで


あなたthen関数にcountの値を渡したい場合は、あなたがresolve()を呼び出すときにそれを渡す必要があります。現時点ではnullを渡しています。


あなたのコードのこのバージョンでは、コールバックとしてresolveを渡すだけで、適切なタイミングでそれを呼び出すためにそれを修正します。longOperationの実行が終了する前に

longOperation(id); 
resolve(null); 

longOperationは非同期関数であるため、resolve(null)が実行されます:

// Example: long operation that takes time to execute 
 
var longOperation = function(id, resolve) { 
 
    var time = 1000 * Math.random(); 
 
    console.log('[' + id + '] Operation started for: ' + time + 'ms'); 
 

 
    setTimeout(function(err) { 
 
    console.log('[' + id + '] Completed operation: ' + time + 'ms'); 
 
    var count = id * 10; 
 
    resolve(count); 
 
    }, 1000 * Math.random()); 
 
}; 
 

 
// Create new promise for longOperation 
 
var longOpPromise = function(id) { 
 
    return new Promise(function(resolve, reject) { 
 
    longOperation(id, resolve); 
 
    }); 
 
}; 
 

 
// Create sequencing 
 
var runLongOperation = function(callback) { 
 
    var count1; 
 
    longOpPromise(1).then(function(count) { 
 
    count1 = count; 
 
    console.log('Count 1: ' + count1); 
 

 
    longOpPromise(2).then(function(count2) { 
 
     console.log('Count 2: ' + count2); 
 
     callback(null, count1, count2); 
 
    }); 
 
    }); 
 
}; 
 

 
// Run 
 
runLongOperation(function(err, count1, count2) { 
 
    if (err) console.error(err); 
 
    console.log('Count 1 ' + count1 + ' | Count 2: ' + count2); 
 
});

1

ここでの主な問題は、あなたの非同期アクション(setTimeout)があなたの約束に関係していないことです。

longOperation(id)の後のresolve(null)は、すぐにnullを返し、longOperation関数のタイムアウト間隔が終了するのを待機しません。このような

何かが動作します:

// Example: long operation that takes time to execute 
var longOperation = function(id) { 

    var time = 1000 * Math.random(); 

    console.log('[' + id + '] Operation started for: ' + time + 'ms'); 

    return new Promise(function(resolve) { 
     setTimeout(function(err) { 
      console.log('[' + id + '] Completed operation: ' + time + 'ms'); 
      var count = id * 10; 
      resolve(count); 
     }, time); 
    }); 

}; 

// Create new promise for longOperation 
var longOpPromise = function(id) { 
    return longOperation(id); 
}; 

私はlongOperationnew Promise内部を移動し、setTimeoutコールバックが処理されるときにのみ解決します。

1

1つの問題は、これらの2行です。

setTimeoutでコールバックが実行されるまで、私は約束が解決しないことを確認するために、二つの第一の機能を組み合わせることになります。

var longOpPromise = function(id) { 

    var time = 1000 * Math.random(); 

    console.log('[' + id + '] Operation started for: ' + time + 'ms'); 

    return new Promise(function(resolve, reject) { 
     setTimeout(function(err) { 
      console.log('[' + id + '] Completed operation: ' + time + 'ms'); 
      var count = id * 10; 
      resolve() // Now the promise won't resolve until here. 
     }, 1000 * Math.random()); 
    }) 


}; 

を私もあなたのようなコールバックとの約束を混合避けるだろうがやっている - を除いてsetTimeoutのような組み込み関数の場合、約束を使用しているなら、コールバックの使用を避けることができます。