2013-05-16 12 views
8

Tôi đã đọc về mô hình Promise và tôi đã cố gắng viết mã một phiên bản bằng PHP với sự trợ giúp của một vài ví dụ và sự hiểu biết của riêng tôi về cách nó hoạt động. Có phải tôi đã đưa ra một ví dụ hợp lý về mẫu Promise hay tôi đã thực hiện điều này không chính xác?Việc triển khai này có phải là một ví dụ hợp lý về Lời hứa trong PHP không?

class PromiseClass { 
    private $callbacks = array(); 
    private $last_return; 
    function promise($promise) { 
     if (get_class($promise) == 'Promise') { 
      return $promise; 
     } else if (is_callable($promise)) { 
      $this->then($promise); 
      return $this; 
     } 
    } 
    public function then (callable $callback) { 
     $this->callbacks[] = $callback; 
     return $this; 
    } 
    public function resolve() { 
     $callback = array_shift($this->callbacks); 
     if (is_callable($callback)) { 
      $this->last_return = $callback($this->last_return); 
     } 
     if (count($this->callbacks) > 0) { 
      $this->resolve(); 
     } 
    } 
} 

Ví dụ sử dụng:

$promiser->promise(function() { 
     echo "sleeping\n"; 
     sleep(3); 
     return 3; 
    }) 
    ->then(function($args) { 
     echo " in second function, $args\n"; 
    }); 
$promiser->resolve(); 
+3

Điều này phù hợp hơn với codereview.stackexchange.com –

+0

@JohnConde là đúng. Tuy nhiên, để giảm bớt sự tò mò của bạn - đây thực sự là một mẫu Promise trong PHP! ... Ngoại trừ việc 'sleep()' đang chặn. Trả lời đến. –

Trả lời

12

thực hiện lời hứa của bạn chủ yếu là chính xác. Tuy nhiên, có một vấn đề: ít nhất trong PHP, nó hầu như là vô dụng và gần như hoàn toàn tương đương với mẫu Observer wikipediamsdnoodesign.

PHP gần như hoàn toàn đơn luồng. sleep cũng không ngoại lệ. Như vậy, toàn bộ Lời hứa của bạn sẽ chặn tập lệnh của bạn cho đến khi hoàn thành. Kết quả là, nhìn thấy như các hoạt động được thực hiện nội tuyến, bạn cũng có thể không bận tâm.

Một cách có thể để loại bỏ vấn đề nhỏ đó là làm cho Lời hứa của bạn thành ngã ba từ tập lệnh chính, có thể sử dụng họ PCNTL của các chức năng. Điều này sẽ cho phép mã Promise chạy trong nền, trong khi kịch bản chính tiếp tục. Khi lời hứa hoàn thành, nó trở lại.

Cách thực hiện việc này được nêu tại http://www.php.net/manual/en/function.pcntl-fork.php#98711. Nó làm cho hoạt động sử dụng của pcntl_fork, cho phép bạn để ngã ba một sợi mới. Nó có nhược điểm - lớn nhất trong số họ là không có khả năng để nhắn tin cho quá trình chính bởi bất cứ điều gì nhưng tín hiệu.

+4

Địa ngục gọi lại xảy ra do đồng bộ hóa nếu bạn muốn thực hiện [đa nhiệm hợp tác xã] (http://en.wikipedia.org/wiki/Computer_multitasking#Cooperative_multitasking). Btw nếu bạn có php 5.5 thì tốt hơn nên sử dụng [generator] (http://www.php.net/manual/en/language.generators.php) (kể từ ngày 20 tháng 6 năm 2013) thay vì lời hứa ... Ohh and ofc bạn có thể có chủ đề trong php với [pthreads extension] (http://pthreads.org/) (từ năm 2012) ... Vì vậy, câu trả lời này là "chủ yếu là vô dụng" ... – inf3rno

+0

Đã tìm kiếm thông tin này tại https://github.com/reactphp/promise. Không có gì nói về khi kịch bản kết thúc. Họ nên thêm liên kết tới bài đăng này trên trang của họ –

+0

pcntl giờ đây cũng hỗ trợ thông tin ngữ cảnh: https://wiki.php.net/rfc/additional-context-in-pcntl-signal-handler –