2013-03-11 35 views
6

Tôi nghĩ rằng tôi hiểu nhầm cách thức hoạt động của các lời hứa Q. Tôi muốn lời hứa đầu tiên của mình để giải quyết trước khi bắt đầu tiếp theo, nhưng điều đó không xảy ra. Đây là mã của tôi:Thực hiện nối tiếp với lời hứa Q

var Q = require('q'); 

function doWork(taskName) { 
    var deferred = Q.defer(); 
    console.log('starting', taskName); 
    setTimeout(function() { 
    console.log('done with', taskName); 
    deferred.resolve(); 
    }); 

    return deferred.promise; 
} 

doWork('task one') 
    .then(doWork('task two')) 
    .then(function() { console.log('all done'); }); 

Mã này sản xuất:

$ node test.js 
    starting task one 
    starting task two 
    done with task one 
    done with task two 
    all done 

tôi hy vọng rằng nó tạo ra:

$ node test.js 
    starting task one 
    done with task one 
    starting task two 
    done with task two 
    all done 

Tôi đang làm gì sai?

Trả lời

7

này hoạt động:

doWork('task one') 
    .then(function() { 
    return doWork('task two') 
    }) 
    .then(function() { 
    console.log('all done'); 
    }); 

Điều đó làm cho cảm giác - chỉ cần gọi doWork trực tiếp trong then() sẽ bắn ra thời gian chờ ngay lập tức, thay vì giving Q một cơ hội để chờ đợi cho đến khi task one hoàn tất.

4

Lý do là doWork cần được tham chiếu dưới dạng hàm. Nếu bạn muốn tham chiếu một hàm bên trong '.then' thì bạn chỉ cần cung cấp tên hàm, bạn không chuyển các tham số. Khi trình phân tích cú pháp thấy .then (doWork ('taskTwo')) nó sẽ chạy doWork ('taskTwo') TRƯỚC KHI. Nó đang cố gắng ràng buộc tham số hàm.

Trong trường hợp này, nếu bạn trả về tham số cho tác vụ tiếp theo trong lời hứa đã giải quyết của tác vụ trước thì trình phân tích cú pháp sẽ gọi doWork với thông số chính xác và theo đúng thứ tự.

var Q = require('q'); 
function doWork(taskNum) { 
    var deferred = Q.defer(); 
    console.log('starting', taskNum); 
    setTimeout(function() { 
     console.log('done with task', taskNum); 
     deferred.resolve(++taskNum); 
    }); 

    return deferred.promise; 
} 

doWork(1) 
.then(doWork) 
.then(function(lastTaskNum) { console.log('all done'); }); 
1

Mẫu mã sử dụng qyêu cầu

var Q  = require('q'), 
    request = require('request'), 
    api  = {}; 


api.post = function (options) { 

    var deferred = Q.defer(); 

    request.post(options, function (error, response, body) { 
      error ? deferred.reject(error) : deferred.resolve(body); 
    }); 

    return deferred.promise; 
}; 

api.get = function (options) { 
    var deferred = Q.defer(); 

    request.post(options, function (error, response, body) { 
      error ? deferred.reject(error) : deferred.resolve(response); 
    }); 

    return deferred.promise; 
} 

api 
    .post({url: 'https://foo.com'}) 
    .then(function (body) { 
      console.log(body); 
      return api.get({url: 'http://myspace.hell'}); 
    }, function (error) { 
      //error handling logic 
    }) 
    .then(function (response) { 
      console.log(response); 
    }, function (error) { 
      //error handling logic 
    }) 
    .done(); //when you are done 

Trong đoạn mã trên, bạn có thể thấy rằng tôi xác định 2 phương pháp API: đượcbài.

Tôi đang sử dụng thư viện request.

  • phương pháp api bài tôi, giải quyết các lời hứa với cơ thể của đối tượng response được trả về bởi request.post()
  • tôi được phương pháp api, giải quyết các lời hứa với phản ứng của the request.get() gọi

Bạn có thể thấy chính xác cách bạn có thể kết nối cuộc gọi 2 api này bằng lời hứa.

Trong đầu tiên sau đó Tôi trả lời lời hứa thứ hai, để tôi có thể thực hiện lời hứa.

Các vấn đề liên quan