簡體   English   中英

一對多的承諾

[英]One-to-many promises

我有一個客戶列表,然后每個客戶都有一系列要運行的任務。 在psudeocode中:

Get all customers
For each customer, get list of tasks
For each task, run task

但是,我想在運行這些任務時利用JavaScript的異步性質。 有了承諾,我可以做一些事情:

getAllCustomers().then(function(customers) {
  var taskGetters = [];
  customers.forEach(function(customer) {
    taskGetters.push(getCustomerTasks(customer).then(function(tasks) {
      var taskDoers = [];

      tasks.forEach(function(task) {
        taskDoers.push(doTask());
      });

      return promise.all(taskDoers);
    });
  });

  return promise.all(taskGetters);
}).then(function() {
  // clean up
}).catch(function() {
  // handle error
});

然而,這遇到了回調所帶來的一些結構性問題 - 我開始嵌套東西而不是保持應有的清晰的psudeo同步結構。 如何在保留承諾的結構優勢的同時解決這個問題?

如果我記得你正在使用藍鳥,那么你可以:

getAllCustomers().map(function(customer) {
  return Promise.map(customer, getCustomerTasks).map(doTask);
}).then(function() {

}).catch(function() {
  // handle error
});

然而,這遇到了回調所帶來的一些結構性問題 - 我開始嵌套東西而不是保持應有的清晰的psudeo同步結構。

不。甚至同步等價物也會嵌套:你在那里有兩個循環:

customers = getAllCustomers()
for each customer in customers
  tasks = getTasklist()
  for each task in tasks
    run(task)

但是,為了更清晰的代碼,我建議使用map而不是forEach手動數組構建:

getAllCustomers()
.then(function(customers) {
  return promise.all(customers.map(function(customer) {
    return getCustomerTasks(customer)
    .then(function(tasks) {
      return promise.all(tasks.map(doTask));
    });
  }));
}).then(function() {
  // clean up
}).catch(function() {
  // handle error
});

一些promise庫甚至可能為.then((X)=>all(X.map(…)))模式提供快捷方法。

你將每個回調都變成一個函數,而不是一個閉包,你將擁有一個更好的結構:

function processTasks(tasks){
  var taskDoers = [];

  tasks.forEach(function(task) {
    taskDoers.push(doTask());
  });

  return promise.all(taskDoers);
}

function processCustomer(customer){
    taskGetters.push(getCustomerTasks(customer).then(processTasks));
}

function processCustomers(customers){
    customers.forEach(processCustomer);
}

function cleanup(){

}
function handle(error){

}
getAllCustomers().then(processCustomers).then(cleanup).catch(handle);

您可以根據需要將盡可能多的閉包分成多個函數。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM